Господа программисты прошу помочь мне, суть проблемы такая: Взялся решать задачу "Составитель кроссвордов", надо из файла прочитать слова, составить кроссворд и вставить в файл, сообразил код, (большенство не мною написаный) и проблема встала такая, когда ввожу следующие слова:
africa
family
engel
brother
charming
design
greatfull
hart
klient
effort
independence
то из кроссворда выподает слово engel, он просто пишет его рядом, хотя место для вставки есть, подскажите плиз как решить эту проблему, код программы ниже, заранее благодарен!!!
//—————————————————————————
#pragma hdrstop
#include <stdio.h>
#include <conio.h>
#define crss_sz 30
#pragma argsused
//—————————————————————————
typedef struct//тип структуры списка слов
{
char **grid;//матрица слов переменной длинны
int m;//количество строк сетки
int n;//количество столбцов сетки
int *len; //массив с размерами соотв. слов из grid
}
Matrix;
void printWords(Matrix M)
{
int i,j;
for (i=0; i<M.m; i++)
{
for (j=0; j<M.len[i]; j++)
printf("%c",M.grid[i][j]);
printf(" %d", M.len[i]);
printf("\n");
}
}
void printMatrix(char M[crss_sz][crss_sz])
{
int i,j;
for (i=0; i<crss_sz; i++)
{
for (j=0; j<crss_sz; j++)
printf("%c",M[i][j]);
printf("\n");
}
}
void readFile(Matrix *Words)
{
FILE *fp;
char c;
int i, j;
fp=fopen("words.txt", "r");
j=0;
i=0;
Words->len=NULL;
do
{
//нужно добавить новую строку в матрицу слов для очередного слова
Words->grid=realloc(Words->grid, (i+1)*sizeof(char *) );
Words->grid[i]=NULL;
c=fgetc(fp);
j=0;
while (c!='\n' && !feof(fp) )
//набираем слово в текущую строку матрицы слов
{
Words->grid[i]=realloc(Words->grid[i], (j+1)*sizeof(char));
Words->grid[i][j]=c;
j++;
c=fgetc(fp);
};
Words->len=realloc(Words->len, (i+1)*sizeof(int));
Words->len[i]=j;
i++;
}
while ( !feof(fp) );
Words->m=i;
fclose(fp);
}
void writeFile(char Cross[crss_sz][crss_sz])
{
FILE *fp;
int i, j;
fp=fopen("crosswords.txt", "w");
for (i=0; i<crss_sz; i++)
{
for (j=0; j<crss_sz; j++)
fputc(Cross[i][j], fp);
fprintf(fp, "\n");
}
fclose(fp);
}
//функция сортировки массива слов по длинне
void sortMatrix(Matrix *Words)
{
int i, j, t;
char *e;
for (i=0; i+1 < Words->m; i++)
for (j=i+1; j < Words->m; j++)
{
if ( Words->len[i] < Words->len[j])
{
e=Words->grid[i];
Words->grid[i]=Words->grid[j];
Words->grid[j]=e;
t=Words->len[i];
Words->len[i]=Words->len[j];
Words->len[j]=t;
}
}
}
//функция копирует слово str в кроссворд по горизонтали,начиная с координат(i,j)
void putLine(char *word, int word_sz, int i, int j, char Cross[crss_sz][crss_sz])
{
int s;
for (s=0; s<word_sz; j++, s++)
Cross[i]
3 апреля 2008 в 12:03
Отлаживайте код (вполне достаточно встроенного отладчика в студию) – так поймёте где происходит ошибочка … и возможно её суть и метод устранения.
2 апреля 2008 в 20:04
Cross[i][j]=word[s];
}
void putCol(char *word, int word_sz, int i, int j, char Cross[crss_sz][crss_sz])
{
int s;
for (s=0; s<word_sz; i++, s++)
Cross[i][j]=word[s];
}
int countWords(int len[], int i)
{
int res=0;
for (i=i-1; i>=0; i–)
if (len[i]>0)
res++;
return res;
}
/* функция пытается поставить слово word в матрицу кроссворда Cross
по горизонтали и возвращает количество найденных пересечений.
ii, jj – координаты начала слова в кроссворде, при которых будет макс.
пересечение с другими словами.
Если функция возвращает 0, то пересечений не найдено */
int WordStandHorizontal(char *word, int word_sz, char Cross[crss_sz][crss_sz], int *ih, int *jh)
{
int i, j, s, res=0, tmp=0;
for (i=0; i<crss_sz; i++)
for (j=0; j<crss_sz – word_sz; j++) //очередная клетка кроссворда
{
for (s=0; s<word_sz; s++)
if ( word[s]==Cross[i][j+s] )
tmp++;
else
/*надо проверить есть ли свободная клетка для след. буквы слова
и не будут ли стоять другие слова по краям этой клетки */
if ( Cross[i][j+s] != ' ' || (Cross[i-1][j+s]!=' ' || Cross[i+1][j+s]!=' ') )
{
tmp=0;
break;
}
//если начало и конец слова не соседствует с лругими словами
if(j-1>=0 && j+s+1<crss_sz && Cross[i][j-1]==' ' && Cross[i][j+s+1]==' ')
if (tmp>res)//если эти условия лучше предыдущих
{
res=tmp;
*ih=i;
*jh=j;
}
}
return res;
}
/*функция пытается поставить слово word в матрицу кроссворда Cross
по вертикали и возвращает количество найденных пересечений.
ii, jj – координаты начала слова в кроссворде, при которых будет макс.
пересечение с другими словами.
Если функция возвращает 0, то пересечений не найдено */
int WordStandVertical(char *word, int word_sz, char Cross[crss_sz][crss_sz], int *iv, int *jv)
{
int i, j, s, res=0, tmp=0;
for (j=0; j<crss_sz; j++)
for (i=0; i<crss_sz – word_sz; i++) //очередная клетка кроссворда
{
for (s=0; s<word_sz; s++)
if ( word[s]==Cross[i+s][j])
tmp++;
else
if ( ( Cross[i+s][j] != ' ') || (Cross[i+s][j-1]!=' ' || Cross[i+s][j+1]!=' ' ))
{
tmp=0;
break;
}
if(i-1>=0 && i+s+1<crss_sz && Cross[i-1][j]==' ' && Cross[i+s+1][j]==' ')
if (tmp>res) //если эти условия лучше предыдущих
{
res=tmp;
*iv=i;
*jv=j;
}
}
return res;
}
/*функция возвращает истину, если ей удалось подставить слово str
размером sz_str в кроссворд Cross */
int tryPutWords(char *word, int word_sz, char Cross[crss_sz][crss_sz])
{
int i, j, ii, jj ;
int ih, jh, iv, jv;
int crossCountH=0, crossCountV=0, wordCount;
//Определим количество пересечений слова word по вертикали и горизонтали
crossCountH=WordStandHorizontal(word, word_sz, Cross, &ih, &jh);
crossCountV=WordStandVertical(word, word_sz, Cross, &iv, &jv);
//определим оптимальное размещение и поставим туда слово
//если слово поставить в кроссворд не удалось, функция возвратит ложь
2 апреля 2008 в 20:04
if (crossCountH > 0 &&crossCountH >=crossCountV)
{
putLine(word, word_sz, ih, jh, Cross);
return 1;
}
else
if ( crossCountV >0 &&crossCountV >crossCountH)
{
putCol(word, word_sz, iv, jv, Cross);
return 1;
}
else
return 0;
}
void drawCross(Matrix *Words, char Cross[crss_sz][crss_sz])
{
int i, j, ii, jj;
int tmp, count, lastCountWords;
//сначала установим в середину кроссворда самое первое слово из матрицы слов
jj=crss_sz/2- Words->len[0]/2;
ii=crss_sz/2;
putLine(Words->grid[0], Words->len[0], ii, jj, Cross);
Words->len[0]=0;
/* Цикл по матрице слов. Он завершиться,
если с последней итерацией количествово слов не изменилоь*/
lastCountWords=countWords(Words->len, Words->m);
count=1;//первое слово уже использовали
while (lastCountWords != countWords(Words->len, Words->m) || count==1 )
{
for (count=0; count < Words->m; count++) //просмотр всех слов из матрицы
if (Words->len[count] != 0) //если слово не удалено
if (tryPutWords(Words->grid[count], Words->len[count],Cross))
//если слово удалось подставить в кроссворд
{
Words->len[count]=0;//удаляем его из матрицы слов
lastCountWords–; //и уменьшаем счетчик
/*ЕСЛИ ЗДЕСЬ УБРАТЬ КОММЕНТАРИИ, МОЖНО БУДЕТ УВИДЕТЬ
СОСТАВЛЕНИЕ КРОССВОРДА ПОЭТАПНО:
printMatrix(Cross);
getch();
*/
}
}
}
void freeMatrix (Matrix *M)
{
int i;
free(M->len);
for (i=0; i<M->m; i++)
free( M->grid[i] );
free(M->grid);
}
void main(void)
{
char Cross[crss_sz][crss_sz];
Matrix Words;
int i, j;
Words.grid=NULL;
Words.m=0;
Words.n=0;
Words.len=NULL;
//очистим кроссвордную сетку
for (i=0; i<crss_sz; i++)
for (j=0; j<crss_sz; j++)
Cross[i][j]=' ';
readFile(&Words);
printf("____________From File:____________\n");
printWords(Words);
sortMatrix(&Words);
printf("____________Sort:____________\n");
printWords(Words);
drawCross(&Words, Cross);
printf("____________Crosswords:____________\n");
printMatrix(Cross);
writeFile(Cross);
getch();
freeMatrix(&Words);
}