#include <stdlib.h>
#include <iostream>
#include <cstdint>
#include <cstring>
using namespace std;
/*
Simplify the implementation below as much as you can.
Even better if you can also improve performance as part of the simplification!
FYI: This code is over 35 lines and over 300 tokens, but it can be written in
5 lines and in less than 60 tokens.
*/
char *func1(char *s, char a, char b)
{
char *aptr;
char *bptr;
char *res;
int i;
if (s[0] == '\0')
{
if ((a == '\0') || (b == '\0'))
return &(s[0]);
else
return NULL;
}
i = 0;
aptr = NULL;
bptr = NULL;
while (aptr == NULL && bptr == NULL)
{
if (s[i] == a)
aptr = s + i;
if (s[i] == b)
bptr = s + i;
if (s[i] == '\0')
{
if ((aptr != s + i) && (bptr != s + i))
return NULL;
}
i++;
}
if (aptr == NULL)
res = bptr;
else if (bptr == NULL)
res = aptr;
else if (aptr < bptr)
res = aptr;
else if (bptr < aptr)
res = bptr;
else
res = aptr;
return res;
}
//-----------------------------------------------------------------------------------
char *func2(char *s, char a, char b) {
char *aptr = strchr(s, a),
*bptr = strchr(s, b);
return 0 == strlen(s) ? (((a == 0) || (b == 0)) ? s : NULL) :
((NULL == aptr) && (NULL == bptr)) ? NULL :
aptr == NULL ? bptr :
bptr == NULL ? aptr :
bptr < aptr ? bptr : aptr;
}
//-----------------------------------------------------------------------------------
struct test {
const char *str;
char a, b;
friend inline ostream& operator << (ostream& stream, test& obj) {
stream << '<' << (obj.str ? obj.str : "NULL") << "|'";
if (isprint(obj.a)) stream << obj.a;
else stream << '\\' << int(obj.a);
stream << "'|'";
if (isprint(obj.b)) stream << obj.b;
else stream << '\\' << int(obj.b);
stream << "'>";
return stream;
}
};
void strshow(char* s, const char* s1) {
if (NULL == s) cout << "NULL";
else if ('\0' == *s) cout << "\"\"";
else cout << (char)*s << "[" << s - s1 << "]";
}
int main(int argc, char **argv) {
test at[] = {
{ "123456789", '7', '3' },
{ "123456789", '7', '8' },
{ "123455432", '7', '3' },
{ "123456789", '5', 'A' },
{ "123456789", 'B', '6' },
{ "123456789", 'x', 'y' },
{ "", 2, 3 },
{ "", 5, 0 },
};
for (int i = 0; i < sizeof(at) / sizeof(at[0]); i++) {
char *pf1 = func1((char*)at[i].str,
at[i].a, at[i].b),
*pf2 = func2((char*)at[i].str,
at[i].a, at[i].b);
cout << i + 1 << " : " << at[i] << " => ";
strshow(pf1, at[i].str);
cout << " ... ";
strshow(pf2, at[i].str);
cout << endl;
}
return 0;
}
Ну і результат виконання тесту тоді потрібно показати для повноти картини:
$ ./strsimpl
1 : => 3[2] ... 3[2]
2 : => 7[6] ... 7[6]
3 : => 3[2] ... 3[2]
4 : => 5[4] ... 5[4]
5 : => 6[5] ... 6[5]
6 : => NULL ... NULL
7 : => NULL ... NULL
8 : => "" ... ""
До речі…
Наші ізраїльські друзі вважають таке рішення неправильним – вони мріяли про щось більш кошерної ;-)
хоча, з іншого боку, я вважаю, що вони просто не вміють точно формулювати свої мрії про кошерності.
Ось дослівно їх умову задачі:
Спрощення реалізації нижче стільки, скільки ви можете.
Ще краще, якщо ви можете також підвищити продуктивність в рамках спрощення!
FYI: Цей код закінчений 35 лінії і більш 300 жетони, але вона може бути записана в 5 лінії і менш ніж 60 жетони.
Тестування показує повну еквівалентність func1() і func2().
Проте, цей епізод підказує, що завдання може мати кілька цікавих варіантів рішення. Пропоную бажаючим активно зайнятися їх пошуками!
Завдання полягає в оптимізації коду, ваше ж рішення звичайне переписування запропонованого алгоритму з метою зменшення кількості рядків.
” код завдання потрібно б спростити майже не розбираючись що цей код повинен робити - за правилами формального синтаксису C ++.”
Але це не дуже відповідає умові в самому завданні – там начебто потрібно спростити саму реалізацію. А значить, слід спочатку постаратися зрозуміти сенс функції, і тоді краще рішення стане очевидним:
Трохи поправив. У вашому варіанті, не перевіряється умова, коли один із параметрів a і b дорівнює ' ′, а другий не знайдений у s, а параметр s != “\0”.
короткий i=0;
do {
if (s[i]==a || s[i]==b) повернути s+i;
} while (s[i ]!=’ ’);
повертати NULL;