What is wrong with this string palindrome program? - c++

THIS PROBLEM IS SOLVED
Given a string, determine if it is a palindrome, considering only alphanumeric characters and ignoring cases.
int Solution::isPalindrome(string A) {
vector<int> v1,v2;
int size = A.size(),a;
for(int i=0; i<size; i++){
if(isalpha(A[i]) || isdigit(A[i]))
{
a = (int)A[i];
v1.push_back(a);
}
if(isalpha(A[size-1-i]) || isdigit(A[size-1-i]))
{
a = (int)A[size-1-i];
v2.push_back(a);
}
}
if(v1==v2)
return 1;
return 0;
}

It doesn't ignore cases, because the comparison v1 == v2 is done with the same case as the original string.
Change
v1.push_back(a);
to
v1.push_back(tolower(a));
And similarly for v2.
Honestly just five minutes testing should have told you this, it's not a hard bug to find.
EDIT
Since I answered this question the code has been changed, to something that no longer compiles. I really don't feel inclined to answer ever changing questions.
EDIT
Well it's changed again. At least it compiles now.

Related

LeetCode Word Break, fail on Online Judge but pass Online test

I met a problem when I was doing leetcode 139, word break.
Given a string s and a dictionary of words dict, determine if s can be segmented into a space-separated sequence of one or more dictionary words. (each dictionary word can be used multiple times.)
For example, given
s = "leetcode",
dict = ["leet", "code"].
Return true because "leetcode" can be segmented as "leet code".
I use basic dynamic programming algorithm, but may implement it in a different way from the popular one on the internet.
Here is the code:
class Solution {
public:
bool wordBreak(string s, unordered_set<string>& wordDict) {
int strlen = s.length();
if(0 == strlen) return true;
vector<bool> sepable(false, strlen);
for(int i = 0; i < strlen; ++i) {
if(wordDict.count(s.substr(0,i+1)) > 0) {
sepable[i] = true;
continue;
}
for(int j = 0; j < i; ++j) {
if(sepable[j] && wordDict.count(s.substr(j+1,i-j)) > 0) {
sepable[i] = true;
break;
}
}
}
return sepable[strlen-1];
}
};
When I ran online judge, it fails at the test:" "aaaaaaa" ["aaaa","aa"]", my code output true, the expected answer is false. However, if I run it on online test, it gives the right output. Also, it works fine on my own virtual machine with clang++.
The difference between online judge and online test is that each online test is only one test. Online judge contains many tests and will fail if anyone of the tests fails. So the problem of my code may lay like this: at some test other than the "aaaaaaa", it gives the right output but cause some potential problem. And that is why my code will fail on "aaaaaaa". However, if I just run this single test, it is fine.
The leetcode website says it may because my code has some undefined behaviors. The previous test case may influence the latter one. I don't know what are all the previous test case and didn't expect anyone here know about it. But I think as long as there are problems in my code, someone can find it.
I think the question is pretty clear this time.
this line parameters are of wrong order vector<bool> sepable(false, strlen); it should be vector<bool> sepable(strlen,false);the length of the vector comes first then the default value and false is implicitly converted to int so the length is set to 0 that gave the undefined behavior

Need to find duplicates from an array in c++, and then put them in another array

this is my first post here and I would be very happy if you could help me.
The task is - Create an array from 6 input numbers, then put the duplicated numbers in another array and then output the array with the repeated numbers.
Do you have any ideas? I'm still a newbie and need some help. Thanks in advance guys !!
EDIT:
I'm not sure if I'm on the right way, that's why I didn't post what I've done yet. But this is it:
#include <iostream>
using namespace std;
int main()
{
int a[6];
int b[6];
int i,z;
for (i=0; i<6; i++){
cin>>a[i];
}
for (z=0; z<6; z++){
if (a[0]==a[1]) b[z]=a[0];
if (a[0]==a[2]) b[z]=a[0];
if (a[0]==a[3]) b[z]=a[0];
if (a[0]==a[4]) b[z]=a[0];
if (a[0]==a[5]) b[z]=a[0];
if (a[1]==a[2]) b[z]=a[1];
if (a[1]==a[3]) b[z]=a[1];
if (a[1]==a[4]) b[z]=a[1];
if (a[1]==a[5]) b[z]=a[1];
if (a[2]==a[3]) b[z]=a[2];
if (a[2]==a[4]) b[z]=a[2];
if (a[2]==a[5]) b[z]=a[2];
if (a[3]==a[4]) b[z]=a[3];
if (a[3]==a[5]) b[z]=a[3];
if (a[4]==a[5]) b[z]=a[4];
else b[z]=0; cout << b[z];
}
return 0;
}
To give you a better understanding of how to solve this, i'll try to show you what is going on via an example.
Lets say you have just entered the 6 numbers you request via cin, and your a[] variable now looks like this in memory:
a[] = { 5, 2, 6, 2, 1, 6 };
The duplicates here are 2 and the 6. (pretty obvious for us humans) :-)
You start to compare the first 2 values in memory: a[0]==a[1], then the first with the third: a[0]==a[2] and so on. If one of these match, you know the value of a[0] has at least one duplicate in memory.
Whenever that happens, you would like to do something that that information. Store it somewhere (like your b[] array) or just output it directly with cout << a[0].
You are now finished with checking a[0] and can continue with a[1] in the same manor, except you do not have to compare with a[0] because you did that in the previous step. Looking at your code, it seems you already understand that you can skip that.
Lets say you really need to store the duplicates. It would help to keep track of how many duplicates you have found.
Pseudo code:
duplicates = 0;
if (a[0] has a duplicate) { b[duplicates] = a[0]; duplicates++; }
if (a[1] has a duplicate) { b[duplicates] = a[1]; duplicates++; }
// etc...
"has a duplicate" would be like the code you had earlier, like: a[0]==a[1] || a[0]==a[2] || a[0]==[3] and so on.
In your example you have just 6 values, so it is not much work to write all the compare statements yourself. If you needed to do this with many more numbers, it would take you ages to write it, and is prone to little mistakes like typo's. Using a for loop would work for few and many numbers:
Pseude code:
duplicates = 0;
for (z = 0 to 6) {
for (y = z+1 to 6) {
if (a[z]==a[y]) {
b[duplicates] = a[z];
duplicates++;
break; // We know it is a duplicate, continue with the next value
}
}
}
But even this is not perfect. If one number occurs more than 2 times in memory, this will store the same duplicate value multiple times.

Split a even-numbered string in c++

I am very new to c++. I am trying to split a string that contains even numbered sub strings till there is no even numbered sub string left. For example, if I input AB ABCD ABC, the output should be A B A B C D ABC. I am trying to do it without tokens, because I don't know how to..
What I have so far only split the first even sub string and it doesn't work if I only have 1 sub string. Can someone please help me out?
Any advise will be much appreciated. Thank you!
string temp = "";
void check(string &str, int &i, int &flag)
{
int count = 0;
int reminder;
do
{
count++;
temp += str[i];
i++;
} while (str[i] != ' ');
i = i - temp.size();
reminder = count % 2;
if (reminder == 0)
flag = 1;
else
flag = 0;
}
void SplitEvenWord(string &str)
{
int i = 0;
int flag = 0;
for (i = 0; i < str.size(); i++)
{
check(str, i, flag);
if (flag == 1)
{
temp.insert(temp.size() / 2, " ");
str.replace(i, temp.size() - 1, temp);
}
}
}
There are two skills that are absolutely vital in software engineering (Well, more than two, but two for now): developing new functions in isolation, and testing things in the simplest possible way.
You say that the code fails if there is only one substring. You don't say how it fails (I should have mentioned clear error reports in the list) so I don't know whether to test your code with an even-length string which it ought to split ("ABCD" => "A B C D") or an odd-length string which it ought to leave alone ("ABC" => "ABC"). Before I try to code these up, I look at your first function:
void check(string &str, int &i, int &flag)
{
...
do
{
count++;
temp += str[i];
i++;
} while (str[i] != ' ');
...
}
Trouble already. The strings I have in mind do not contain any spaces, so the loop cannot terminate. This code will run past the end of the string into whatever happens to be in that memory space, which will cause undefined behavior. (If you don't know that term, it means that there's no telling what will happen, but if you're lucky the program will just crash.)
Fix that, try running that code on "ABC" and "ABCD" and "A" and "" and "ABC DEF", and get it working perfectly. Once it does, take a look at your other function. Don't test it with random typing, test it with short, clearly defined strings. Once it works perfectly, try longer, more complicated ones. If you find a string which causes it to fail, hold onto it! That string will lead you to a bug.
That should be enough to get you started.
I'm writing this as an answer because it was too long to fit as a comment.
I have a couple of suggestions that may help you to figure out what the problem is.
Separate "check" into at least two functions, one to split the string into individual words and check them and one to check the length of the string.
Test the "check" and "tokenize" functions by separately and see if they give you the expected answers. Work on them individually until they are correct.
Separate the formatting of the answers out of "SplitEvenWord" into a separate function.
"SplitEvenWord" should then be nothing more than calling the functions you created as a result of the steps above.
When I'm stuck, I always try to break the problem down into small bite sized pieces that I know I can get working. Eventually, the problem becomes assembling the already working pieces of the solution into a larger function that solves the original problem.

Professionalise this code [closed]

Closed. This question is off-topic. It is not currently accepting answers.
Want to improve this question? Update the question so it's on-topic for Stack Overflow.
Closed 11 years ago.
Improve this question
I have been programming for about 3 years now and feel confident in my skills. But recently I began working alongside embedded systems and working on other peoples code and have begun to question how good my code is.
I see all these complex answers on SO and think I would have done that with a vector and if statements and wonder if I am any more than a beginner as I was self taught and don't really know my level.
So I was wondering if more experienced programmers could show me ho to do things better.
This is code I wrote to for an rpg game to pick a target to attack. using it as an example could you show me better/more advanced/professional ways of doing it.
int FindTarget(Player &player);
{
int aimPoint[5] = 0;
for(int i = 0; i <= 5; i++)
{
if(player.team[i].exist == true)
{
// set random starting point between 1 - 3
aimPoint[i] = random /3;
// add a point if you hve an elemental advantage minus if not
if(player.team[i].type == weak)
{
aimPoint += 1;
}
else if(player.team[i].type == strong)
{
aimPoint -= 1;
}
//add for front row minus for back
if(i == 1 || i== 3)
{
aimPoint += 1;
}
else
{
aimPoint -= 1;
}
}
}
return 0;
}
EDIT: If you don't have the time or effort to show me examples I would appreciate a good book that a beginner/intermediate could understand.
Comment #1:
This line starts at 0, and goes exactly once? Why is it a loop?
for(int i = 0; i <= 0; i++)
Comment #2:
Don't compare a boolean against true.
if(player.team[i].exist == true)
Just re-write it to:
if(player.team[i].exist)
Comment #3:
Professionals rarely use hardcoded values.
Why is this value 5?
int aimPoint[5] = 0;
Instead, make it clear:
int aimPoint[TARGET_SIZE] = 0;
Similarly, change
aimPoint[i] = random /3;
to:
aimPoint[i] = random /INITIAL_TARGET_VALUE;
This is pointless; it's not a loop, it's a single pass.
for(int i = 0; i <= 0; i++)
ahem since nobody mentioned it, let me point this one out:
int FindTarget(Player &player);
{
int aimPoint[5] = 0;
...
return 0
}
to roughly
void FindTarget(const Player &player)
{
std::vector<int> aimPoint(5, 0);
...
}
Also, since there is no knowing what the code should do (and how 'aimPoint' is related to teams; guessing doesn't help because none of it is used, aimPoint is discarded?), I don't have anything else than fixing the obvious breakage that was above
---- Edit from a comment
The handling of random seems misguided. Someone suggested that you might have meant random %3 + 1;
I noted that too but decided there is nothing to base the assumption on. Perhaps random is already an int in the range [3, 12).
Also, random % 3 won't yield a uniform distribution, so you'd need to do something else
For many applications, rand() will perform admirably when used correctly, but with the current sad state of affairs, rand() is very rarely used correctly.
The problem is that of distribution
Here is how I would write it.
void FindTarget(Player &player);
{
int aimPoint[5];
for(int i = 0; i <= 5; ++i)
{
if(!player.team[i].exist)
continue;
// set random starting point between 1 - 3
aimPoint[i] = random / 3;
// add a point if you hve an elemental advantage minus if not
switch(player.team[i].type) {
case weak:
++aimPoint[i];
break;
case strong:
--aimPoint[i];
break;
}
//add for front row minus for back
if(i == 1 || i== 3)
++aimPoint[i];
else
--aimPoint[i];
}
}
That piece of code:
// set random starting point between 1 - 3
aimPoint[i] = random /3;
don't get you random number between 1 and 3, try this:
aimPoint[i] = random % 3 + 1

Why are empty expressions legal in C/C++?

int main()
{
int var = 0;; // Typo which compiles just fine
}
How else could assert(foo == bar); compile down to nothing when NDEBUG is defined?
This is the way C and C++ express NOP.
You want to be able to do things like
while (fnorble(the_smurf) == FAILED)
;
and not
while (fnorble(the_smurf) == FAILED)
do_nothing_just_because_you_have_to_write_something_here();
But! Please do not write the empty statement on the same line, like this:
while (fnorble(the_smurf) == FAILED);
That’s a very good way to confuse the reader, since it is easy to miss the semicolon, and therefore think that the next row is the body of the loop. Remember: Programming is really about communication — not with the compiler, but with other people, who will read your code. (Or with yourself, three years later!)
I'm no language designer, but the answer I'd give is "why not?" From the language design perspective, one wants the rules (i.e. the grammar) to be as simple as possible.
Not to mention that "empty expressions" have uses, i.e.
for (i = 0; i < INSANE_NUMBER; i++);
Will dead-wait (not a good use, but a use nonetheless).
EDIT: As pointed out in a comment to this answer, any compiler worth its salt would probably not busy wait at this loop, and optimize it away. However, if there were something more useful in the for head itself (other than i++), which I've seen done (strangely) with data structure traversal, then I imagine you could still construct a loop with an empty body (by using/abusing the "for" construct).
OK, I’ll add this to the worst case scenario that you may actually use:
for (int yy = 0; yy < nHeight; ++yy) {
for (int xx = 0; xx < nWidth; ++xx) {
for (int vv = yy - 3; vv <= yy + 3; ++vv) {
for (int uu = xx - 3; uu <= xx + 3; ++uu) {
if (test(uu, vv)) {
goto Next;
}
}
}
Next:;
}
}
I honestly don't know if this is the real reason, but I think something that makes more sense is to think about it from the standpoint of a compiler implementer.
Large portions of compilers are built by automated tools that analyze special classes of grammars. It seems very natural that useful grammars would allow for empty statements. It seems like unnecessary work to detect such an "error" when it doesn't change the semantics of your code. The empty statement won't do anything, as the compiler won't generate code for those statements.
It seems to me that this is just a result of "Don't fix something that isn't broken"...
Obviously, it is so that we can say things like
for (;;) {
// stuff
}
Who could live without that?
When using ;, please also be aware about one thing. This is ok:
a ? b() : c();
However this won't compile:
a ? b() : ; ;
There are already many good answers but have not seen the productive-environment sample.
Here is FreeBSD's implementation of strlen:
size_t
strlen(const char *str)
{
const char *s;
for (s = str; *s; ++s)
;
return (s - str);
}
The most common case is probably
int i = 0;
for (/* empty */; i != 10; ++i) {
if (x[i].bad) break;
}
if (i != 10) {
/* panic */
}
while (1) {
; /* do nothing */
}
There are times when you want to sit and do nothing. An event/interrupt driven embedded application or when you don't want a function to exit such as when setting up threads and waiting for the first context switch.
example:
http://lxr.linux.no/linux+v2.6.29/arch/m68k/mac/misc.c#L523