Все технические форумы на одном сайте Удобный поиск информации с популярных форумов в одном месте
Вопрос: Слова исходной строки записать в алфавитном порядке

Дана строка, содержащая слова, разделённые разделителями(пробелами, табуляторами),
в начале и конце строки также могут быть разделители.Сформировать новую строку,в которой слова и исходной строки записаны в алфавитном порядке и разделятся одним пробелом.В начале строки и вконце строки не должно быть разделительных символов.

программа должна работать без использования string.h , проблема возникла с написанием функции сортировки


C
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
#include<stdio.h>
 
 
void Work(char* from,char * to);
void sort(int n, int i, char to[i]);
char * skipspace(char *p)
 
int main()
{
for(;;)
{
 
 
char from[80]="",to[80]="";
 
 
printf("Input string, 0-exit: "); gets(from);
if (from[0]=='0') break;
printf("Source: %s\n",from);
Work(from,to);
printf("Result: %s.\n",to);
}
return 0;
}
 
char * skipspace(char *p){
for (;*p==' ' || *p=='\t';p++);
return p;
}
 
 
void sort(int n, int i, char to[i])/*Функция сортировки*/
{
 for(i = 0; i < n; i++) {
       for(int j = 0; j < n - i - 1; j++) {
           if(to[j] > to[j+1]) {
              int tmp = to[j];
              to[j] = to[j+1];
              to[j+1] = tmp;
           }
        }
    }
    return sort(n, i, a[i]);
}
 
 
void Work(char* from,char* to)
{
char* tmp;
int i;
 
for (i=0;*(from=skipspace(from));i++);{
{
if(i) *to+1=' ';
tmp = from;
for(;*from && *from!='_'&& *from!=' ';*to++=*from++);
sort(to-(from-tmp),from-tmp);
}
*to='\0';
}
}
Ответ:
C
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
#include <stdio.h>
#include <malloc.h>
#include <ctype.h>
int  s_cmp(const char* s1, const char* s2);
void isort(char* a[], int n);
 
int copy_sort(char* d, char* s){
    char** a, *p;
    int    n,  i;
 
    n = i = 0;
    p = s;
    do {
        if(isalpha(*p))
            i = 1;
        else if(i){
            ++n;
            i = 0;
        }
    } while(*p++ != '\0'); 
    
    if(! n)
        return 0;
 
    a = (char**)malloc((size_t)n * sizeof(char*));
    if(a == NULL)
        return 0;
 
    for(i = 0; *s; s = p){
        while(*s && !isalpha(*s))
            ++s;
 
        p = s;
        while(isalpha(*p))
            ++p;
 
        if(p > s){
            a[i++] = s;
            if(*p)
                *p++ = '\0';
        }
    }
 
    isort(a, n);
    for(i = 0; i < n; ++i){
        p = a[i];
        while((*d = *p) != '\0'){
            ++d;
            ++p;
        }
        if((i + 1) < n)
            *d++ = ' ';
    }
    *d = '\0';
 
    free(a);
    return 1;
}
 
 
int main(void){
    char d[64];
    char s[64] = "fox, wolf, cat, tiger, duck, bat, dog, bear, pig";
 
    if(copy_sort(d, s))
        puts(d);
    return 0;
}
 
//сравнение строк минуя регистр символа
int s_cmp(const char* s1, const char* s2){
    int i;
    while(!(i = toupper(*s1) - toupper(*s2)) && *s1){
        ++s1;
        ++s2;
    }
    if(i < 0)
        i = -1;
    else if(i > 0)
        i = 1;
    return i;
}
 
//сортировка вставкой
void isort(char* a[], int n){
    int   i, j;
    char* k;
    for(i = 1; i < n; ++i){
        k = a[i];
        j = i - 1;
        while((j >= 0) && (s_cmp(a[j], k) > 0)){
            a[j + 1] = a[j];
            --j;
        }
        a[j + 1] = k;
    }
}
Вопрос: Символы в словах исходной строки записать в алфавитном порядке

Дана строка, содержащая слова, разделенные одним или несколькими разделительными символами (пробелами, табуляторами), в начале строки и в конце строки также могут находиться разделительные символы. Сформировать новую строку, в которой символы в словах исходной строки записаны в алфавитном порядке. Слова в новой строке разделяются одним пробелом. В начале строки и в конце строки не должно быть разделительных символов.
Ответ:
Код C
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
#include <stdio.h>
#include <stdlib.h>
#include <string.h>
#include <ctype.h>
 
//-----------------------------------------------------------------------------
int getWord(const char str[],
            const char** begin,
            const char** end) {
    for (; *str && isspace(*str); ++str) { ; }
    *begin = str;
 
    for (; *str && !isspace(*str); ++str) { ; }
    *end = str;
 
    return *end - *begin;
}
//-----------------------------------------------------------------------------
int cmp(const void* a, const void* b) {
    return tolower(*(char*)a) - tolower(*(char*)b);
}
//-----------------------------------------------------------------------------
char* func(const char src[], char dst[]) {
    char* result = dst;
    const char* begin, * end;
    int len;
 
    while ((len = getWord(src, &begin, &end))) {
        strncpy(result, begin, len);
        qsort(result, len, sizeof(char), cmp);
        result += len;
        *result++ = ' ';
        src = end;
    }
 
    if (dst < result) {
        result--;
    }
 
    *result = 0;
 
    return dst;
}
//-----------------------------------------------------------------------------
 
#define MAXLEN 128
 
int main() {
    char source[MAXLEN], result[MAXLEN];
 
    if (fgets(source, MAXLEN, stdin)) {
        printf("[%s]\n", func(source, result));
    }
 
    return 0;
}
Вопрос: Получить исходную строку из md5-хэша

А как получить исходную строку, на основании которой был сгенерен хэш?
md5, например

		
		var s = "12345";
		byte[] b = Encoding.UTF8.GetBytes(s);

		var h = new MD5CryptoServiceProvider();
		var hb = h.ComputeHash(b);
		var hs = Convert.ToBase64String(hb);

		byte[] a = Convert.FromBase64String(hs);

		s = System.Text.Encoding.UTF8.GetString(a);	//	Получается мусор вместо изначального значения
Ответ: ЕвгенийВ,

Сломали уже этот MD5 давно, признан ненадёжным и не рекомендуется к использованию. Сейчас его можно использовать разве что, как хеширующую функцию не для защиты данных и криптографии, так как довольно быстр.
Вопрос: Найти и заменить в исходной строке все вхождения заданной подстроки

Найти в исходной строке все вхождения (но не более девяти) заданной подстроки и заменить их на другую строку с указанием номера очередного вхождения . Допустимые символы - прописные русские и латинские буквы; символ разделитель "_".
ПРИМЕР
Исходная строка : ПОЛИЛИ_ЛИЛИЮ
Какую строку заменить : ЛИ
На какую подстроку заменить : СТО
Результат : ПОСТО1СТО2_СТО3СТО4Ю
Ответ: Vollan, не ёрничайте. Вы создали ещё одну тему, которую мне пришлось удалить.
Название темы:
Найти в исходной строке все вхождения
Сообщение:
Найти в исходной строке все вхождения (но не более девяти) заданной подстроки и заменить их на другую строку с указанием номера очередного вхождения . Допустимые символы - прописные русские и латинские буквы; символ разделитель "_".
ПРИМЕР
Вопрос: Сформировать новую строку, состоящую из чисел длин слов в исходной строке

Дана строка символов, состоящая из произвольного текста на английском языке, слова разделены
пробелами. Сформировать новую строку, состоящую из чисел длин слов в исходной строке.
Ответ:
Сообщение от Kot2128
спасибо.
а как реализовать, чтобы я сам вводил фразу,а мне выводилась строка состоящая из чисел длин слов в исходной строке?
Зависит от типа приложения. Если вы разрабатываете консольное приложение, то можно считать строку из консоли.
На примере кода MaxSlim
C#
1
string text = Console.ReadLine();
Вопрос: В исходной строке а$ определить и вывести слова, которые встречаются в строке по одному разу

В исходной строке а$ определить и вывести слова, которые встречаются в строке по одному разу
Ответ:
Visual Basic
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
Sub Slova_1raz()
    Dim i%, B, vX, Dic As Object, Msg$
    Const a$ = "В исходной строке определить и вывести слова которые встречаются в строке по одному разу"
    B = Split(a, " ")
    Set Dic = CreateObject("Scripting.Dictionary"): Dic.CompareMode = 1
    For i = 0 To UBound(B)
        If Dic.Exists(B(i)) Then
            Dic(B(i)) = 0
        Else
            Dic(B(i)) = 1
        End If
    Next i
    For Each vX In Dic.Keys
        If Dic(vX) = 1 Then Msg = Msg & vX & " "
    Next
    MsgBox Msg
End Sub
Вопрос: Как получить текстовую строку из текущего

Как получить текстовую строку, соответствующую текущему элементу CComboBox?
Ответ:
Как получить текстовую строку, соответствующую текущему элементу CComboBox?
Вопрос: Выделения из исходной строки подстроки символов

Написать программу выделения из исходной строки подстроки символов заданной длины с указанного номера позиции, Pascal-string.
Как переделать из Pascal-string в Z-string?


Код ASM
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
;Часть строки, следующую за первым вхождением заданного символа переписать
;в обратном порядке заданное число раз;(использовать процедуры)
.686
.model flat,stdcall
option casemap:none
 
mem_alloc proto :dword,:dword,:dword ; прототипы функций, используемых в программе
reverce proto :dword,:dword,:dword,:dword,:dword
 
include \masm32\include\msvcrt.inc
include \masm32\include\windows.inc
include \masm32\include\user32.inc
 
includelib \masm32\lib\msvcrt.lib
includelib \masm32\lib\user32.lib
 
.data
msg db 'Введите строку',0dh,0ah,1 ; единицы в конце строк нужны для того, чтобы функция CharToOem могла перекодировать весь текст за один раз
msg1 db 'Введите позицию символа начала подстроки ',0dh,0ah,1 ; до символа нуля
msg2 db 'Введите количество повторов подстроки',0dh,0ah,1
msg_exit db 0ah,'Для выхода нажмите клавишу ESC, для повторного ввода нажмите любую другую клавишу',0dh,0ah,1
msg_no db 0ah,'Позиция символа введена неверно',0dh,0ah,0
crlf db 0dh,0ah,0 ; знаки первода строки и каретки, будут использованы после ввода символа для 
; перевода курсора на новую строку
fmt db '%u',0
 
.code
 
start proc 
; локальные переменные
local string[MAX_PATH]:byte ; буффер для ввода строки, 260 байт
local position,str_len,crep:dword ; переменные для хранения начальной позиции подстроки, длины
; строки и количества повторений соответственно
 
invoke CharToOem,offset msg,offset msg ; функция перекодирует текст сообщений из кодировки CP1251 в CP866 для правильного отображения в консоли
mov msg+sizeof msg-1,0 ; заменим единицы в конце текстовых сообщений на нули
mov msg1+sizeof msg1-1,0
mov msg2+sizeof msg2-1,0
mov msg_exit+sizeof msg_exit-1,0
 
@gets:
 
invoke printf,offset msg ; выводим на экран приглашение к вводу строки
 
lea esi,string ; регистр esi указывает на начало буфера для ввода строки
invoke gets,esi ; функция ввода строки
 
invoke strlen,esi ; измерим длину введённой строки
mov str_len,eax ; и сохраним полученное значение в переменной и регистре
mov edi,eax
dec edi ; уменьшим на единицу полученное значение, так как нумерация символов в строке идёт с нуля
 
invoke printf,offset msg1 ; вывод на экран приглашения к вводу значения позиции начала подстроки
 
invoke scanf,offset fmt,addr position ; функция преобразует введённые цифры в число, в сответствии с указанным форматом ( в нашем случае
dec position ; - беззнаковое десятичное число)
cmp position,edi ; уменьшим введённое значение на 1 , сравним его с длиной строки
jb m1 ; если оно больше или равно длины строки
 
invoke printf,offset msg_no ; выведем сообщение об ошибочном вводе
jmp exit
 
m1:
invoke printf,offset msg2 ; иначе продолжаем выводом приглашения к вводу количества повторов подстроки
invoke scanf,offset fmt,addr crep 
 
dec crep ; полученное значение уменьшаем на единицу
 
mov ebx,str_len ; вычислим длину подстроки
sub ebx,position
cmp ebx,1
jnz m2
 
invoke printf,offset msg_no ; выведем сообщение об ошибочном вводе если длина подстроки равна единице
jmp exit
 
m2:
invoke mem_alloc,crep,ebx,str_len ; вызовем функцию выделения памяти под новую строку
; передав ей в качестве параметров кол-во повторов подстроки, её длину и длину исходной строки
 
mov ebx,eax ; и сохраним возращённый указатель на выделенный блок памяти в регистре ebx
 
invoke reverce,esi,ebx,position,str_len,crep
 
invoke printf,ebx ; выводим строку на экран
invoke free,ebx ; освобождаем память
exit:
invoke printf,offset msg_exit ; выводим сообщение о способе завершения программы
 
invoke _getch ; ожидание нажатия клавиши пользователем
cmp al,1bh
je @f
invoke getchar
jmp @gets
@@:
invoke _exit ; завершение программы
 
start endp
 
; —-----------------------------------------------------------------------
 
reverce proc uses ebx pstr:dword,pnewstr:dword,psubstr:dword,szstr:dword,crep
 
mov esi,pstr ;
переданный в процедура указатель на исходную строку
mov edi,pnewstr ; указатель на выделенный блок памяти
mov ecx,psubstr ; номер начального символа подстроки
rep movsb ; копируем исходную строку до начала подстроки в новую
 
mov ecx,szstr ; размер исходной строки
sub ecx,psubstr ; получаем размер подстроки
mov edx,ecx ; сохраняем в регистре edx для повторного использования
mov ebx,edi ; указатель на начало подстроки сохраняем в ebx
 
m1:
lodsb ; в цикле заносим в стек символы подстроки, подлежащие реверсированию
push ax
loop m1
 
mov ecx,edx ; восстанавливаем счётчик
m2:
pop ax ; перезаписывем в новую строку в обратном порядке ( последний символ строки будет лежать в стеке первым)
stosb
loop m2
 
mov esi,ebx ; устанавливаем указаетель на начало перевернутой подстроки
mov ecx,crep ; количество повторов подстроки
; регистр edi указывает на первый байт после последнего символа скопированной строки
m3:
push ecx ; сохранив счётчик в стеке
mov ecx,edx
rep movsb ; копируем подстроку 
pop ecx ; нужное число раз
loop m3
xor al,al ; в конец новой строки записываем символ нуля
stosb
 
ret ; возврат из процедуры
reverce endp
 
; —-----------------------------------------------------------------------
 
mem_alloc proc var1:dword,var2:dword,var3:dword
 
mov eax,var1 ; количество повторов умножаем на
mul var2 ; длину подстроки
add eax,var3 ; прибавляем к произведению длину строки
inc eax ; прибавляем единицу (для записи нулевого байта - признака конца новой строки)
 
invoke malloc,eax ; выделяем память под формируемую строку
 
ret
mem_alloc endp
end start
Ответ: edi указывает на Pascal-строку
Код ASM
1
2
3
4
5
6
7
8
    push    edi
    movzx   ecx, byte ptr [edi]
    lea esi, 1[edi]
    cld
rep movsb
    mov al, cl
    stosb
    pop edi
и вот он уже указывает на Z-строку

Добавлено через 7 минут
Сообщение от anna_smith
invoke strlen,esi ; измерим длину введённой строки
Сообщение от anna_smith
xor al,al ; в конец новой строки записываем символ нуля
stosb
Че-то это мало похоже на работу с Паскалевскими строками.
Вопрос: Составить новую строку из слов исходной строки заданной длины

Пытаюсь разобраться, как в ассемблере работает цикл по строке.
Пишу процедуру, которая составляет новую строку из слов исходной строки заданной длины
Assembler
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
NewString proc
        push ebp
        mov ebp, esp
        push esi
        push edi
        
        mov esi, [ebp + 8]  ; доступ к аргументу 4 (строка, из которой будут копироваться слова)
        mov edi, [ebp + 16] ; доступ к аргументу 2 (строка, в которую будут копироваться слова) 
        mov al, [ebp + 12] ; доступ к аргументу 3 (пока не используется)
 
        xor edx, edx    ; обнуление регистра
 
        dec esi
 
        ; переход к следующему слову
    L1: inc esi
        mov cl, [esi]   ; Заносим в регистр cl очередной символ
        test cl, cl
        jz END    ; Тут переход к выводу
        cmp cl, ' '
        jz PR ; Если пробел, то переходим к проверке числа букв
Правильно ли я написал цикл? И как правильно объявить переменную под счетчик букв?
Ответ:
Assembler
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
.686
.model flat, stdcall
option casemap :none
 
        include \masm32\include\windows.inc
 
        include \masm32\include\user32.inc
        include \masm32\include\kernel32.inc
        include \masm32\include\masm32.inc
 
        includelib \masm32\lib\user32.lib
        includelib \masm32\lib\kernel32.lib
        includelib \masm32\lib\masm32.lib
.data
        aszMsgInstant   db      0Dh, 0Ah, 'Instant:', 0Dh, 0Ah, 0
        aszMsgResult    db      0Dh, 0Ah, 'Result:', 0Dh, 0Ah, 0
        aszPressEnter   db      0Dh, 0Ah, 0Dh, 0Ah, "Press ENTER to exit", 0
        Delimiter       db      ' '
        uiLength        dd      3
        aszString       db      '    99   ghj tyt tyyt t    ui    uou hj', 0
.data?
        hConsoleOutput  HANDLE  ?
        hConsoleInput   HANDLE  ?
        Result          dd      ?
        Buffer          db      1024 dup(?)
        BufLen          dd      ?
 
.code
 
Process proc    lpSrcStr:DWORD, lpDestStr:DWORD, nLength:DWORD
 
        xor     ebx,    ebx             ;количество скопированных слов
        mov     esi,    [lpSrcStr]
        mov     edi,    [lpDestStr]
 
        ;пропуск разделителей
        @@SkipDelimiters:
                lodsb
                cmp     al,     [Delimiter]
        je      @@SkipDelimiters
        or      al,     al
        jz      @@Exit
        ;выделение слова из строки
        mov     edx,    esi             ;(edx-1) - на начало слова
        @@ExtractWord:
                or      al,     al      ;строка завершилась?
                je      @@Break
                cmp     al,     [Delimiter]
                je      @@Break
 
                lodsb
        jmp     @@ExtractWord
@@Break:
        mov     ecx,    esi             ;(esi-1) - на последнюю букву слова
        sub     ecx,    edx             ;ecx - длина слова
        cmp     ecx,    [nLength]
        jne     @@Continue
        ;длина слова равна требуемой - копируем слово в новую строку
        inc     ecx                     ;копируем не только слово, но и разделитель за ним
        sub     esi,    ecx
        rep     movsb
        inc     ebx                     ;количество скопированных слов
@@Continue:
        or      al,     al
        jnz     @@SkipDelimiters
@@Exit:
        cmp     ebx,    1               ;если слова копировались, то записать ноль по адресу [edi-1]
        adc     edi,    -1              ;если искомых слов не нашлось, то записать ноль по адресу [edi]
        mov     [edi],  al
        mov     eax,    ebx
        ret
Process endp
 
main    proc
 
        ; получение описателей ввода и вывода консоли
        invoke  GetStdHandle,   STD_INPUT_HANDLE
        mov     hConsoleInput,  eax
 
        invoke  GetStdHandle,   STD_OUTPUT_HANDLE
        mov     hConsoleOutput, eax
 
        invoke  ClearScreen
 
        ;вывод исходных данных
        invoke  WriteConsole, hConsoleOutput, ADDR aszMsgInstant,\
                LENGTHOF aszMsgInstant - 1, ADDR BufLen, NULL
        invoke  WriteConsole, hConsoleOutput, ADDR aszString,\
                LENGTHOF aszString - 1, ADDR BufLen, NULL
        ;обработка
        invoke  Process,        ADDR aszString, ADDR Buffer, [uiLength]
        mov     [Result],       eax
        ;вывод результата
        invoke  WriteConsole, hConsoleOutput, ADDR aszMsgResult,\
                LENGTHOF aszMsgResult - 1, ADDR BufLen, NULL
        invoke  StrLen, ADDR Buffer
        mov     [BufLen],       eax
        invoke  WriteConsole, hConsoleOutput, ADDR Buffer,\
                BufLen, ADDR BufLen, NULL
        ;ожидание нажатия ENTER
        invoke  WriteConsole, hConsoleOutput, ADDR aszPressEnter,\
                LENGTHOF aszPressEnter - 1, ADDR BufLen, NULL
        invoke  ReadConsole, hConsoleInput, ADDR Buffer,\
                LENGTHOF Buffer, ADDR BufLen, NULL
 
        invoke  ExitProcess, 0
main    endp
 
end     main
Вопрос: Получить новую строку, состоящую из цифр исходной строки

В ячейке А3 содержится строка, состоящая из букв и цифр. Получить новую строку, состоящую из цифр исходной строки. Результат вывести в ячейку С3. Макрос назначить автофигуре.
Ответ:
Visual Basic
1
2
3
4
5
6
Function DelLett(S as string) As string
   for i%=1 to len(S)
       q$=mid$(S,i%,1)
       if isNumeric(q$) then DelLett=DelLett & q$
   next i%
End Function
Применяй эту функцию к содержимому ячейки - получишь то, что заказывал.