Справочник функций

Ваш аккаунт

Войти через: 
Забыли пароль?
Регистрация
Информацию о новых материалах можно получать и без регистрации:

Почтовая рассылка

Подписчиков: -1
Последний выпуск: 19.06.2015

Пара задачек на С

4.8K
15 марта 2005 года
Neighbour
43 / / 15.03.2005
Я здесь новичок, так что извините, если чего не так.
Не очень срочно, так что, если будет свободное время, напишите код, пожалуйста. На работе парюсь, времени на учебу нет вообще. Понимаю, что лучше, кончно, самому, но, повторюсь, некогда. Если это слишком нагло, то извините, может хоть какие нибудь советы дадите по организации алгоритма. Заранее всем спасибо.

Задачи:

1. Рассматривая элементы строки прямоугольной матрицы координатами точки в n-мерном пространстве, определить номера точек, расстояние d между которыми максимально :

2. Отредактировать заданное предложение, удаляя из него слова-серии, а также те слова, которые уже встречались в предложении раньше.
425
15 марта 2005 года
sq_deep
498 / / 18.02.2005
Цитата:
Originally posted by Neighbour
Рассматривая элементы строки прямоугольной матрицы координатами точки в n-мерном пространстве, определить номера точек, расстояние d между которыми максимально

Код:
#include <stdio.h>
#include <math.h>

#define M 4     // количество точек
#define N 5     // размерность пространства

// матрица из M точек размерности N
static double matrix[M][N] =
{
    1.0, 2.0, 3.0, 4.0, 5.0,
    2.2, 3.3, 5.5, 2.3, 8.9,
    3.3, 4.5, 7.6, 3.7, 6.2,
    4.4, 8.3, 5.0, 2.6, 3.3
};

// вычисление расстояния между двумя точками
static double dist(double* p1, double* p2)
{
    double dDistSqr = 0.0;
    for (int i = 0; i < N; i++)
        dDistSqr += pow(*(p1 + i) - *(p2 + i), 2.0);
    return sqrt(dDistSqr);
}

// основная программа
void main()
{
    int i, j;       // параметры циклов
    puts("Начальные данные");
    for (i = 0; i < M; i++)         // по строкам
    {
        for (j = 0; j < N; j++)     // по столбцам
            printf("%f ", matrix[j]);
        puts("");
    }

    double dMax = -1.0; // вычисляемое максимальное расстояние
    int iMax = -1;      // индекс первой найденной точки
    int jMax = -1;      // индекс второй найденной точки
    for (i = 0; i < M - 1; i++)         // индекс первой точки
    {
        for (j = i + 1; j < M; j++)     // индекс второй точки
        {
            double dDist = dist(matrix, matrix[j]);
            if (dDist > dMax)   // расстояние больше, чем последнее максимальное?
            {
                dMax = dDist;
                iMax = i;
                jMax = j;
            }
        }
    }

    printf("\nСамые отдалённые точки %d и %d. Их координаты:\n", iMax, jMax);
    for (i = 0; i < N; i++)
        printf("%f ", matrix[iMax]);
    puts("");
    for (i = 0; i < N; i++)
        printf("%f ", matrix[jMax]);
    printf("\n\nРасстояние между ними %f.\n", dMax);
}
Результат
Код:
Начальные данные
1.000000 2.000000 3.000000 4.000000 5.000000
2.200000 3.300000 5.500000 2.300000 8.900000
3.300000 4.500000 7.600000 3.700000 6.200000
4.400000 8.300000 5.000000 2.600000 3.300000

Самые отдалённые точки 1 и 3. Их координаты:
2.200000 3.300000 5.500000 2.300000 8.900000
4.400000 8.300000 5.000000 2.600000 3.300000

Расстояние между ними 7.844743.
С вас 20 копеек, Сосед.
Цитата:
Отредактировать заданное предложение, удаляя из него слова-серии, а также те слова, которые уже встречались в предложении раньше.

Расскажите, что такое слова-серии, и, возможно, будете счастливы.

4.8K
15 марта 2005 года
Neighbour
43 / / 15.03.2005
Цитата:
Расскажите, что такое слова-серии, и, возможно, будете счастливы.



Спасибочки, куды алтын бросить? Слова-серии - одинаковые слова, стоящие рядом.

425
15 марта 2005 года
sq_deep
498 / / 18.02.2005
Цитата:
Originally posted by Neighbour
Спасибочки, куды алтын бросить?

Сосед, алтын — это 3 копейки, а мне надо 20. Пошлите мне их по электронной почте.

4.8K
15 марта 2005 года
Neighbour
43 / / 15.03.2005
Цитата:
Originally posted by sq_deep
Сосед, алтын — это 3 копейки, а мне надо 20. Пошлите мне их по электронной почте.



Ну, звиняйте, мы люди темные, гимназиев не кончали. Гривенник что-ли хотите, что-т не пойму?
Енто какая почта "електронная"? Я про такое и не слыхивал.

4.8K
15 марта 2005 года
Neighbour
43 / / 15.03.2005
Все, отработал, иду домой к жене и детям. До завтра всем! Спасибо, sq_deep, баальшущее!;)
4.8K
29 марта 2005 года
Neighbour
43 / / 15.03.2005
Все возвращается на круги своя...
Начал делать текстовую задачу сам. Как сделать - представляю, однако столкнулся с рядом проблем, касающихся синтаксиса и структур данных.

Вводимую строку считаваю в char inString [1024]
Далее пытаюсь в цикле for (int i=0; i<= len(inStr); i++) проверить функцией inAlpha является ли очередной символ буквой. Уже на этом этапе компилятор выдает сообщение о несовпадении типов. Далее возникает вопрос: "Допустим окончанием очередного слова будет символ, предшествующий знаку препинания или пробелу. Где, в каком массиве или структуре какой-нибудь сохранить все найденные слова для последующей обработки?" Сравнить их и отредактировать по условию я, пожалуй, смогу. И еще: Предложение-то надо отредактировать, удалив лишь слова, а знаки препинания по-идее нужно сохранить. А они уже будут удалены блоком разбивки предложения на слова. В общем, запутался я уже порядком - неделю до ночи сижу, а результатов пока никаких. Подскажите, что к чему, пожалуйста.
425
29 марта 2005 года
sq_deep
498 / / 18.02.2005
Да, Сосед, я Вам искренне сочувствую. Задача предполагает довольно запутанное решение.

К тому же, мелкие детали задания не определены, по крайней мере, в Вашей постановке.

Например, как Вы считаете, фраза aaa,bbb,bbb,ccc должна превратиться в aaa,,,ccc, в aaa,,bbb,ccc или в aaa,bbb,,ccc?

А фраза aaa,bbb,bbb,ccc,bbb может дать
[1] aaa,,,ccc,bbb
[2] aaa,,,ccc,
[3] aaa,bbb,,ccc,
[4] aaa,,bbb,ccc,
Какой вариант имеется в виду в задании?

А как насчёт фразы aaa,bbb,bbb,bbb,ccc?

Ещё маленькое замечание. Вы упоминаете некую функцию inAlpha. ANSI версия этой функции называется isalpha().

Ну, а по поводу реализации могу предложить следующее.

[SIZE=3]1.[/SIZE] Если можно пользоваться C++, то помогла бы STL. Там есть массивы переменной длины и всякие полезные алгоритмы.

[SIZE=3]2.[/SIZE] Если надо делать на чистом C, то я бы сделал анализ входной строки в два прохода примерно так.

[SIZE=3]2.1.[/SIZE] Разместим массив из 512 структур типа
 
Код:
struct tagWord
{
    char* m_pStart;   // начало слова во входной строке
    int m_len;        // длина слова
};
tagWord aWord[512];
Надеюсь, понятно, что 512 — маскимальное число слов, которые могут быть записаны во входной строке длиной 1024.
[SIZE=3]2.2.[/SIZE] Проанализируем входную строку от начала до конца и заполним массив aWord. В процессе этого получим и количество слов в исходной фразе.
[SIZE=3]2.3.[/SIZE] Переносим в выходную строку все символы, предшествующие первому слову.
[SIZE=3]2.4.[/SIZE] Проходим по массиву. Для каждого слова определяем, достойно ли оно перенесения в выходную строку. Если слово не совпадает ни с предыдущим, ни со следующим и не встречалось ранее, переносим его в выходную строку вместе со всеми следующими за ним разделителями. Если слово не прошло проверку, копируем в выходную строку только разделители.

Короче говоря, задача противная, но решаемая.

Дерзайте. Желаю удачи.
4.8K
29 марта 2005 года
Neighbour
43 / / 15.03.2005
Цитата:
Originally posted by sq_deep
Да, Сосед, я Вам искренне сочувствую. Задача предполагает довольно запутанное решение.

К тому же, мелкие детали задания не определены, по крайней мере, в Вашей постановке.

Например, как Вы считаете, фраза aaa,bbb,bbb,ccc должна превратиться в aaa,,,ccc, в aaa,,bbb,ccc или в aaa,bbb,,ccc?

А фраза aaa,bbb,bbb,ccc,bbb может дать
[1] aaa,,,ccc,bbb
[2] aaa,,,ccc,
[3] aaa,bbb,,ccc,
[4] aaa,,bbb,ccc,
Какой вариант имеется в виду в задании?

А как насчёт фразы aaa,bbb,bbb,bbb,ccc?

Ещё маленькое замечание. Вы упоминаете некую функцию inAlpha. ANSI версия этой функции называется isalpha().

Ну, а по поводу реализации могу предложить следующее.

[SIZE=3]1.[/SIZE] Если можно пользоваться C++, то помогла бы STL. Там есть массивы переменной длины и всякие полезные алгоритмы.

[SIZE=3]2.[/SIZE] Если надо делать на чистом C, то я бы сделал анализ входной строки в два прохода примерно так.

[SIZE=3]2.1.[/SIZE] Разместим массив из 512 структур типа
 
Код:
struct tagWord
{
    char* m_pStart;   // начало слова во входной строке
    int m_len;        // длина слова
};
tagWord aWord[512];
Надеюсь, понятно, что 512 — маскимальное число слов, которые могут быть записаны во входной строке длиной 1024.
[SIZE=3]2.2.[/SIZE] Проанализируем входную строку от начала до конца и заполним массив aWord. В процессе этого получим и количество слов в исходной фразе.
[SIZE=3]2.3.[/SIZE] Переносим в выходную строку все символы, предшествующие первому слову.
[SIZE=3]2.4.[/SIZE] Проходим по массиву. Для каждого слова определяем, достойно ли оно перенесения в выходную строку. Если слово не совпадает ни с предыдущим, ни со следующим и не встречалось ранее, переносим его в выходную строку вместе со всеми следующими за ним разделителями. Если слово не прошло проверку, копируем в выходную строку только разделители.

Короче говоря, задача противная, но решаемая.

Дерзайте. Желаю удачи.



Имеется в виду вариант 3: aaa,bbb,,ccc,
По п. 2.2: Чем анализировать входную строку?

425
29 марта 2005 года
sq_deep
498 / / 18.02.2005
Цитата:
Originally posted by Neighbour
Имеется в виду вариант 3: aaa,bbb,,ccc,


Это сильно упрощает анализ. Не надо проверять следующее слово, достаточно только убедиться, что оно не встречалось ранее. Тогда анализ можно сделать за один проход исходной строки.

Цитата:
Originally posted by Neighbour
Чем анализировать входную строку?


Примерно в таком духе:

Код:
int iWord;   // индекс текущего выделяемого слова
char* pPos;  // текущая позиция просмотра входной строки после анализа очередного слова
//...
// пропустим разделители
for (; *pPos && !isalpha(*pPos); pPos++)
    ;
if (!*pPos)
    return;    // конец входной строки

aWord[iWord].m_pStart = pPos;   // начало слова найдено
// посчитаем теперь его длину
for (aWord[iWord].m_len = 0;
     *pPos && isalpha(*pPos);
     pPos++, aWord[iWord].m_len++)
    ;
4.8K
29 марта 2005 года
Neighbour
43 / / 15.03.2005
Цитата:


aWord[iWord].m_pStart = pPos; // начало слова найдено
// посчитаем теперь его длину
for (aWord[iWord].m_len = 0;
*pPos && isalpha(*pPos);
pPos++, aWord[iWord].m_len++)
;



Я вообще запутался - for (aWord[iWord].m_len = 0. Что, можно выражению присвоить значение? Что значит (aWord[iWord].m_len, aWord[iWord].m_pStart в смысле после точки - переменная, я еще такого не встречал. sq_deep, ну пожалуйста, если будет время, сегодня там, завтра, через неделю, напишите мне всю программку, а то я чувствую, что ничего у меня не выйдет. А я поучусь на ней, проанализирую. Я уже разочаровался в своем выборе учиться на программиста заочно. Просто не знаю как организовать свое обучения. Т.е. у меня есть конкретные задания в контрольных работах, ну я и начинаю в книжках искать то, что касается конкретной проблемы, например в данном примере - работа с текстом. А примеры в литературе все типовые, под конкретную ситуацию не применишь. Вот такие пироги. Вообще, реально ли самому разобраться во всем этом засилье литературы и действительно применять это в решении практических задач?

425
29 марта 2005 года
sq_deep
498 / / 18.02.2005
Да, Соседушка, не своим делом, видно, Вы занялись. Ладно, потрачу на Вас полчаса, хотя меня на форуме уже раз критиковали за написание пары программ для партизаночки...

Ждите, надейтесь, будет. Но только с синтаксисом Вам придётся всё-таки разобраться. Писать книгу про C у меня нет ни времени, ни желания.
425
29 марта 2005 года
sq_deep
498 / / 18.02.2005
Код:
#include <stdio.h>      // standard i/o functions
#include <ctype.h>      // isalpha()
#include <string.h>     // string functions

struct tagWord
{
    char* pStart;       // указатель на начало слова
    int len;            // длина слова
};

static const int cbLine = 1023;     // максимальная длина исходной строки
static char szSource[cbLine + 1];   // исходная строка
static char szRes[cbLine + 1];      // строка-результат
static char* pRes = szRes;          // указатель на заполняемый символ результата
static tagWord aWord[cbLine / 2];   // массив слов
static int nWords = 0;              // количество слов в массиве

// подпрограмма ввода исходных данных
static void Read()
{
    puts("Enter source line.");
    gets(szSource);
}

// подпрограмма определения "нашего" слова
static bool IsLastWordOur()
{
    for (int i = 0; i < nWords; i++)
    {
        if (aWord.len == aWord[nWords].len &&
            !strnicmp(aWord.pStart, aWord[nWords].pStart, aWord.len))
        {
            return false;   // слово не наше: уже есть в массиве
        }
    }
    // слово наше (в массиве его нет)
    nWords ++;  // в массиве стало на одно слово больше
    return true;
}

// подпрограмма выделения одного слова
static char* ExtractWord(char* pCur)
{
    // перепишем разделители в строку-результат
    for (; *pCur && !isalpha(*pCur); pCur++)
        *pRes++ = *pCur;
    if (!*pCur)
        return NULL;        // конец строки

    // выделим слово
    aWord[nWords].pStart = pCur;    // запомним начало слова
    // найдём длину слова
    for (aWord[nWords].len = 0;
        *pCur && isalpha(*pCur);
        pCur++, aWord[nWords].len++)
        ;
    if (IsLastWordOur())    // слово наше?
    {
        // да, скопируем его в результат
        strncpy(pRes, aWord[nWords - 1].pStart, aWord[nWords - 1].len);
        pRes += aWord[nWords - 1].len;  // и передвинем указатель на длину добавленного
    }
    return pCur;
}

// подпрограмма обработки данных
static void Process()
{
    char* pCur = szSource;      // указатель на текущий просматриваемый символ
    while (pCur = ExtractWord(pCur))    // пока есть выделенное слово
        ;
}

// подпрограмма вывода данных
static void Print()
{
    *pRes = 0;  // строка должна завершаться символом '\0'
    puts(szRes);
}

///////////////////////////////////////////////
//           Главная программа Соседа
///////////////////////////////////////////////
void Neighbour()
{
    Read();         // введём данные
    Process();      // обработаем данные
    Print();        // напечатаем данные
}
4.8K
29 марта 2005 года
Neighbour
43 / / 15.03.2005
Цитата:
Originally posted by sq_deep
 
Код:
///////////////////////////////////////////////
//           Главная программа Соседа
///////////////////////////////////////////////
void Neighbour()
{
    Read();         // введём данные
    Process();      // обработаем данные
    Print();        // напечатаем данные
}



Это void main что-ли. Круто! Я не достоин этого. Век не забуду! Может и я чем полезен буду, лет эдак через триста, как программировать научусь:D

425
29 марта 2005 года
sq_deep
498 / / 18.02.2005
Цитата:
Originally posted by Neighbour
Это void main что-ли. Круто! Я не достоин этого. Век не забуду! Может и я чем полезен буду, лет эдак через триста, как программировать научусь:D


Да, это меняете на void main() и всё будет OK.

И кстати, с Вас 20 копеек.

[COLOR=green]Насчёт Вашей подписи «И это пройдет!» у меня есть история. У царя Соломона, как известно, был перстень со словами «И это минет». Считается, что перстень был один, но на самом деле их было много, около тысячи. Текст был написан давно, когда знаки пунктуации в иврите ещё не использовались. Поэтому мы по традиции воспринимаем фразу как утвердительную. А на самом-то деле в конце там должен стоять вопросительный знак, потому что царь награждал им одну из своих 300 жён и 700 наложниц тогда, когда был недоволен сексом с ней.[/COLOR] :D

Реклама на сайте | Обмен ссылками | Ссылки | Экспорт (RSS) | Контакты
Добавить статью | Добавить исходник | Добавить хостинг-провайдера | Добавить сайт в каталог