Определение последнего вхождения подстроки в строку - C (СИ)
Формулировка задачи:
Написать следующие функции в двух вариантах: с использованием индексов и указателей.
В строке string1 определяет последнее вхождение в нее строки string2. Возвращает указатель на начало вхождения. В случае неуспеха возвращается -1.
const char* rat(const char* string1, const char* string2)
Функции типа strstr использовать НЕЛЬЗЯ!
С комментариями, пожалуйста!
Решение задачи: «Определение последнего вхождения подстроки в строку»
textual
Листинг программы
#include <stdio.h>
char* strrstr(const char* const haystack, const char* const needle)
{
int flag = 0;
const char* haystackIterator = haystack;
const char* haystackSearchStartPtr = NULL;
const char* needleIterator = needle;
size_t needleLength = 0;
/* empty needle case */
if (*needle == '\0')
{
return NULL;
}
/*
here we do the following:
1) sending needle iterator to the end of needle
2) getting needle end pointer from #1
3) while going to end pointer, determine if both strings are same
(only if they are of same length that is)
4) check if we can actually perform a search -- haystack can be shorter
than needle
*/
flag = 1;
while ((*needleIterator != '\0') && (*haystackIterator != '\0'))
{
if (*needleIterator != *haystackIterator)
{
flag = 0;
}
needleIterator++;
haystackIterator++;
}
/* checking if needle is longer than haystack */
if (*needleIterator != '\0')
{
return NULL;
}
/*
checking if both are of same length and had same character composition
the whole time
*/
if (flag && (*needleIterator == '\0') && (*haystackIterator == '\0'))
{
return (char*) haystack;
}
needleLength = needleIterator - needle;
/* sending haystack iterator to (end of haystack - needle length) position */
while (*(haystackIterator + needleLength) != '\0')
{
haystackIterator++;
}
/* starting search from end */
haystackSearchStartPtr = haystackIterator;
while (haystackSearchStartPtr >= haystack)
{
/* iterating through both, comparing at the same time */
needleIterator = needle;
haystackIterator = haystackSearchStartPtr;
while ((*needleIterator != '\0') && (*needleIterator == *haystackIterator))
{
haystackIterator++;
needleIterator++;
}
/* if we reached end of needle, then we had positively compared both */
if (*needleIterator == '\0')
{
return (char*) haystackSearchStartPtr;
}
haystackSearchStartPtr--;
}
return NULL;
}
void Test(void)
{
printf("'%s'\n", strrstr("This is a test string!", "string"));
printf("'%s'\n", strrstr("This is a test string!", "This"));
printf("'%s'\n", strrstr("This is a test string!", "DEMO"));
printf("'%s'\n", strrstr("This is a test string!", "st"));
printf("'%s'\n", strrstr("This is a test string!", "This is a test string!"));
printf("'%s'\n", strrstr("This is a test string!", ""));
}
int main(void)
{
Test();
return 0;
}
Объяснение кода листинга программы
- В функции
strrstrопределяется последний вхождения подстроки в строку. - Если подстрока пустая, то возвращается
NULL. - Переменная
flagинициализируется как 1. - В цикле пока оба указателя не достигнут конца своих строк, выполняется сравнение символов.
- Если символы не совпадают, то значение переменной
flagменяется на 0. - Если подстрока длиннее строки, то возвращается
NULL. - Если подстрока и строка имеют одинаковую длину и состав, то возвращается адрес последнего символа строки.
- Если подстрока короче строки, то выполняется поиск с начала строки.
- Если подстрока найдена, то возвращается адрес первого символа подстроки.
- В функции
Testвыводятся результаты тестирования функцииstrrstr. - В строке
This is a test string!подстрокиstring,This,DEMO,stиThis is a test string!находятся в конце строки. - Подстрока
This is a test string!находится в начале строки. - Подстрока `` не найдена в строке.
- В функции
mainвызывается функцияTest. - Программа завершается с возвращаемым значением 0.