#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;
}
Well, the result of the test then needs to be shown for completeness.:
$ ./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 : => "" ... ""
By the way…
Our Israeli friends think this decision is wrong – they dreamed of something more kosher ;-)
Although, on the other hand, I consider, that they just don't know how to accurately articulate their kosher dreams.
Here is literally their problem statement:
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.
Testing shows complete equivalence of func1() и func2().
Nevertheless, this episode suggests, that the problem can have several interesting solutions. I suggest those who wish to actively engage in their search!
The challenge is to optimize the code, your solution is the usual rewriting of the proposed algorithm in order to reduce the number of lines.
” the task code should be simplified almost without understanding what this code should do - according to the rules of the formal syntax of C ++.”
But this does not really match the condition in the task itself. – there seems to be a need to simplify the implementation itself. Which means, you should first try to understand the meaning of the function, and then the best solution becomes obvious:
Corrected a little. In your option, condition is not checked, when one of the parameters a and b is ‘ 0′, and the second one is not found in s, and the parameter s != “\0”.
short i=0;
do {
if (s[i]==a || s[i]==b) return s+i;
} while (s[i ]!=’ ’);
return NULL;