Пара задачек на С
Не очень срочно, так что, если будет свободное время, напишите код, пожалуйста. На работе парюсь, времени на учебу нет вообще. Понимаю, что лучше, кончно, самому, но, повторюсь, некогда. Если это слишком нагло, то извините, может хоть какие нибудь советы дадите по организации алгоритма. Заранее всем спасибо.
Задачи:
1. Рассматривая элементы строки прямоугольной матрицы координатами точки в n-мерном пространстве, определить номера точек, расстояние d между которыми максимально :
2. Отредактировать заданное предложение, удаляя из него слова-серии, а также те слова, которые уже встречались в предложении раньше.
Рассматривая элементы строки прямоугольной матрицы координатами точки в n-мерном пространстве, определить номера точек, расстояние d между которыми максимально
#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.
Расскажите, что такое слова-серии, и, возможно, будете счастливы.
Спасибочки, куды алтын бросить? Слова-серии - одинаковые слова, стоящие рядом.
Спасибочки, куды алтын бросить?
Сосед, алтын — это 3 копейки, а мне надо 20. Пошлите мне их по электронной почте.
Сосед, алтын — это 3 копейки, а мне надо 20. Пошлите мне их по электронной почте.
Ну, звиняйте, мы люди темные, гимназиев не кончали. Гривенник что-ли хотите, что-т не пойму?
Енто какая почта "електронная"? Я про такое и не слыхивал.
Начал делать текстовую задачу сам. Как сделать - представляю, однако столкнулся с рядом проблем, касающихся синтаксиса и структур данных.
Вводимую строку считаваю в char inString [1024]
Далее пытаюсь в цикле for (int i=0; i<= len(inStr); i++) проверить функцией inAlpha является ли очередной символ буквой. Уже на этом этапе компилятор выдает сообщение о несовпадении типов. Далее возникает вопрос: "Допустим окончанием очередного слова будет символ, предшествующий знаку препинания или пробелу. Где, в каком массиве или структуре какой-нибудь сохранить все найденные слова для последующей обработки?" Сравнить их и отредактировать по условию я, пожалуй, смогу. И еще: Предложение-то надо отредактировать, удалив лишь слова, а знаки препинания по-идее нужно сохранить. А они уже будут удалены блоком разбивки предложения на слова. В общем, запутался я уже порядком - неделю до ночи сижу, а результатов пока никаких. Подскажите, что к чему, пожалуйста.
К тому же, мелкие детали задания не определены, по крайней мере, в Вашей постановке.
Например, как Вы считаете, фраза 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 структур типа
{
char* m_pStart; // начало слова во входной строке
int m_len; // длина слова
};
tagWord aWord[512];
[SIZE=3]2.2.[/SIZE] Проанализируем входную строку от начала до конца и заполним массив aWord. В процессе этого получим и количество слов в исходной фразе.
[SIZE=3]2.3.[/SIZE] Переносим в выходную строку все символы, предшествующие первому слову.
[SIZE=3]2.4.[/SIZE] Проходим по массиву. Для каждого слова определяем, достойно ли оно перенесения в выходную строку. Если слово не совпадает ни с предыдущим, ни со следующим и не встречалось ранее, переносим его в выходную строку вместе со всеми следующими за ним разделителями. Если слово не прошло проверку, копируем в выходную строку только разделители.
Короче говоря, задача противная, но решаемая.
Дерзайте. Желаю удачи.
Да, Сосед, я Вам искренне сочувствую. Задача предполагает довольно запутанное решение.
К тому же, мелкие детали задания не определены, по крайней мере, в Вашей постановке.
Например, как Вы считаете, фраза 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 структур типа
{
char* m_pStart; // начало слова во входной строке
int m_len; // длина слова
};
tagWord aWord[512];
[SIZE=3]2.2.[/SIZE] Проанализируем входную строку от начала до конца и заполним массив aWord. В процессе этого получим и количество слов в исходной фразе.
[SIZE=3]2.3.[/SIZE] Переносим в выходную строку все символы, предшествующие первому слову.
[SIZE=3]2.4.[/SIZE] Проходим по массиву. Для каждого слова определяем, достойно ли оно перенесения в выходную строку. Если слово не совпадает ни с предыдущим, ни со следующим и не встречалось ранее, переносим его в выходную строку вместе со всеми следующими за ним разделителями. Если слово не прошло проверку, копируем в выходную строку только разделители.
Короче говоря, задача противная, но решаемая.
Дерзайте. Желаю удачи.
Имеется в виду вариант 3: aaa,bbb,,ccc,
По п. 2.2: Чем анализировать входную строку?
Имеется в виду вариант 3: aaa,bbb,,ccc,
Это сильно упрощает анализ. Не надо проверять следующее слово, достаточно только убедиться, что оно не встречалось ранее. Тогда анализ можно сделать за один проход исходной строки.
Чем анализировать входную строку?
Примерно в таком духе:
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++)
;
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, ну пожалуйста, если будет время, сегодня там, завтра, через неделю, напишите мне всю программку, а то я чувствую, что ничего у меня не выйдет. А я поучусь на ней, проанализирую. Я уже разочаровался в своем выборе учиться на программиста заочно. Просто не знаю как организовать свое обучения. Т.е. у меня есть конкретные задания в контрольных работах, ну я и начинаю в книжках искать то, что касается конкретной проблемы, например в данном примере - работа с текстом. А примеры в литературе все типовые, под конкретную ситуацию не применишь. Вот такие пироги. Вообще, реально ли самому разобраться во всем этом засилье литературы и действительно применять это в решении практических задач?
Ждите, надейтесь, будет. Но только с синтаксисом Вам придётся всё-таки разобраться. Писать книгу про C у меня нет ни времени, ни желания.
#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(); // напечатаем данные
}
// Главная программа Соседа
///////////////////////////////////////////////
void Neighbour()
{
Read(); // введём данные
Process(); // обработаем данные
Print(); // напечатаем данные
}
Это void main что-ли. Круто! Я не достоин этого. Век не забуду! Может и я чем полезен буду, лет эдак через триста, как программировать научусь:D
Это void main что-ли. Круто! Я не достоин этого. Век не забуду! Может и я чем полезен буду, лет эдак через триста, как программировать научусь:D
Да, это меняете на void main() и всё будет OK.
И кстати, с Вас 20 копеек.
[COLOR=green]Насчёт Вашей подписи «И это пройдет!» у меня есть история. У царя Соломона, как известно, был перстень со словами «И это минет». Считается, что перстень был один, но на самом деле их было много, около тысячи. Текст был написан давно, когда знаки пунктуации в иврите ещё не использовались. Поэтому мы по традиции воспринимаем фразу как утвердительную. А на самом-то деле в конце там должен стоять вопросительный знак, потому что царь награждал им одну из своих 300 жён и 700 наложниц тогда, когда был недоволен сексом с ней.[/COLOR] :D