singlepost

Помогите с решением задачи С << На главную или назад  

Господа программисты прошу помочь мне, суть проблемы такая: Взялся решать задачу "Составитель кроссвордов", надо из файла прочитать слова, составить кроссворд и вставить в файл, сообразил код, (большенство не мною написаный) и проблема встала такая, когда ввожу следующие слова:
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 ответов в теме “Помогите с решением задачи С”

  1. 3
    Человек Имени ответил:

    Отлаживайте код (вполне достаточно встроенного отладчика в студию) – так поймёте где происходит ошибочка … и возможно её суть и метод устранения.

  2. 2
    Евгений Сапсалев ответил:

    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);

    //определим оптимальное размещение и поставим туда слово
    //если слово поставить в кроссворд не удалось, функция возвратит ложь

  3. 1
    Евгений Сапсалев ответил:

    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);
    }

Клуб программистов работает уже ой-ой-ой сколько, а если поточнее, то с 2007 года.