#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;