Поменять местами самое длинное и самое короткое слово - C (СИ)
Формулировка задачи:
Друзья,пожалуйста, помогите мне с этой программкой:
Пользователь вводит с клавиатуры строку. Необходимо поменять местами самое
длинное и самое короткое слово.
Мучаюсь с этой программой уже второй день. Она то правильно всё выводит, то нет.
Заранее спасибо! Буду очень благодарен
#include <stdio.h>
#include <string.h>
#include <locale.h>
#include <stdlib.h>
void X_NAME(char *str);
int main()
{ setlocale(LC_ALL, "Rus");
printf("Для работы программы введите,пожалуйста, предложение на английском языке!\n");
char *str;
str = malloc( sizeof(*str) * 1536 );
fgets(str,4048,stdin);
X_NAME(str);
printf("%s\n", str);
free( str );
return 0;
}
void X_NAME(char *str)
{
int minStart = 0, minEnd = 0, maxStart = 0, maxEnd = 0;//min_word_start, min_word_End, min_word_Start, min_word_End
int i = 0;
int k = 0;
while ((str[i] != '\0') && (str[i] != ' ') && (str[i] != ',') && (str[i] != '.') && (str[i] != '!') && (str[i] != '?'))
i++;
minEnd = i;
maxEnd = i;
while (str[i] != '\0')
{
while ((str[i] != '\0') && (str[i] != ' ') && (str[i] != ',') && (str[i] != '.') && (str[i] != '!') && (str[i] != '?'))
i++;
if ((i-k) > (maxEnd - maxStart))
{
maxStart = k;
maxEnd = i;
printf("min %d %d max %d %d\n", minStart, minEnd, maxStart, maxEnd);
}
if ((i-k) < (minEnd - minStart))
{
minStart = k;
minEnd = i;
printf("min %d %d max %d %d\n", minStart, minEnd, maxStart, maxEnd);
}
i++;
while ((str[i] != '\0') && ((str[i] == ' ') || (str[i] == ',') || (str[i] == '.') || (str[i] == '!') || (str[i] == '?')))
k++;
k = i;
}
printf("min %d %d max %d %d\n", minStart, minEnd, maxStart, maxEnd);
char str2[strlen(str)];//С помощью функции мы задаем массив размером введеной пользователем строки.
if (minStart < maxStart)
{
for (i = 0; i < minStart; i++)
str2[i] = str[i];
int j = maxStart;
for (i; i < minStart + maxEnd - maxStart; i++)
str2[i] = str[j++];
j = minEnd;
for (j; j < maxStart; j++)
str2[i++] = str[j];
j = minStart;
for (i, k = i; i < k + minEnd - minStart; i++)
str2[i] = str[j++];
for (i; i < strlen(str); i++)
str2[i] = str[i];
}
if (minStart > maxStart)
{
for (i = 0; i < maxStart; i++)
str2[i] = str[i];
int j = minStart;
for (i; i < maxStart + minEnd - minStart; i++)
str2[i] = str[j++];
j = maxEnd;
for (j; j < minStart; j++)
str2[i++] = str[j];
j = maxStart;
for (i, k = i; i < k + maxEnd - maxStart; i++)
str2[i] = str[j++];
for (i; i < strlen(str); i++)
str2[i] = str[i];
}
if (minStart == maxStart)
strcpy(str2, str);// функция,которая копирует.
str2[strlen(str)] = '\0';
strcpy(str, str2);
}Решение задачи: «Поменять местами самое длинное и самое короткое слово»
textual
Листинг программы
#include <stdio.h>
#include <string.h>
#include <ctype.h>
#define is_delim(c) (isspace((c)) || ispunct((c)))
typedef unsigned char uchar;
char* swap_min_max(char* s){
int n1, n2, k;
uchar* p1, *p2, *e1, *e2;
uchar* t, c, *p = (uchar*)s;
//поиск мин/макс слова
n1 = n2 = k = 0;
do {
if(*p && !is_delim(*p))
++k;
else if(k > 0){
if((k < n1) || !n1){
n1 = k;
p1 = p - k;
e1 = p;
}
if(k > n2){
n2 = k;
p2 = p - k;
e2 = p;
}
k = 0;
}
} while(*p++ != '\0');
if(!n1 || !n2 || (p1 == p2))
return s;
//...
if(p1 > p2){
t = p1, p1 = p2, p2 = t;
t = e1, e1 = e2, e2 = t;
}
for(;p2 != e2; ++p2, ++p1, ++e1){
for(p = p2; p > p1; --p){
c = *p;
*p = *(p - 1);
*(p - 1) = c;
}
}
for(--e2; p1 != e1; --e1){
for(p = p1; p < e2; ++p){
c = *p;
*p = *(p + 1);
*(p + 1) = c;
}
}
return s;
}
int main(void) {
char s[256];
strcpy(s, "Для работы программы введите,пожалуйста");
puts(s);
puts( swap_min_max(s) );
putchar('\n');
strcpy(s, "begin (APACHE) <- -> {IIS}, over");
puts(s);
puts( swap_min_max(s) );
putchar('\n');
strcpy(s, "Заранее спасибо! Буду очень благодарен.");
puts(s);
puts( swap_min_max(s) );
return 0;
}
Объяснение кода листинга программы
- В функции swap_min_max() происходит поиск двух самых длинных слов в строке s.
- Для этого используется цикл, который проходит по каждому символу строки.
- Если текущий символ является первым символом слова, которое не является разделителем (пробел или знак препинания), то увеличивается счетчик k, отслеживающий длину текущего слова.
- Если текущий символ является последним символом слова, и предыдущий символ не является разделителем, то это слово считается одним из самых длинных, и его индексы сохраняются в переменных n1, p1, e1 и n2, p2, e2.
- Если после прохода по всем символам строки в переменных n1 и n2 не было найдено ни одного слова, или n1 == n2, то функция возвращает исходную строку без изменений.
- Если были найдены два разных слова, то они меняются местами с помощью двух вложенных циклов.
- В первом цикле слова перемещаются влево, а во втором - вправо.
- В конце функции возвращается измененная строка.
- В функции main() строка s изначально содержит текст
Для работы программы введите,пожалуйста. - После выполнения функции swap_min_max() строка s содержит
ечаг,пожалуйста. - Затем строка s изменяется на
begin (APACHE) <- -> {IIS}, over, и после выполнения функции swap_min_max() становитсяover,begin (APACHE) <- -> {IIS}. - В конце программы строка s содержит
Заранее спасибо! Буду очень благодарен., а после выполнения функции swap_min_max() становится!ударь благодар спасибо Заранее.