I am trying to list the First set of a given grammar with this function:
Note:
char c - the character to find the first set;
first_set - store elements of the corresponding first set;
q1, q2 - the previous position;
rule- store all the grammar rule line by line listed below;
for the first time the parameters are ('S', 0, 0).
void findfirst(char c, int q1, int q2){
if(!(isupper(c)) || c=='$'){
first_set[n++] = c;
}
for(int j=0;j<rule_number;j++){
if(rule[j][0]==c){
if(rule[j][2]==';'){
if(rule[q1][q2]=='\0')
first_set[n++] = ';';
else if(rule[q1][q2]!='\0' &&(q1!=0||q2!=0))
findfirst(rule[q1][q2], q1, (q2+1));
else
first_set[n++] = ';';
}
else if(!isupper(rule[j][2]) || rule[j][2]=='$')
first_set[n++] = rule[j][2];
else
findfirst(rule[j][2],j,3);
}
}
}
But found that if the given grammar looks like this:
S AC$
C c
C ;
A aBCd
A BQ
B bB
B ;
Q q
Q ;
(which the left hand side or any capital letters in the right hand side are non-terminal, and any small case letters are terminal)
the function couldn't correctly output the first set for S, since it will stop at finding the first set of Q and store ';' to the first set and won't go on to find C's first set.
Does anyone have a clue? Thanks in advance.
It is extremely inefficient to compute FIRST sets one at a time, since they are interdependent. For example, in order to compute the FIRST set of A , you need to also compute the FIRST set of B, and then because B can derive the emoty string, you need the FIRST set of Q.
Most algorithms compute all of them in parallel, using some variation of a transitive closure algorithm. You can do this with a depth-first search, which seems to be what you are attempting, but it might be easier to implement the least fixed point algorithm described in the Dragon book (and Wikipedia.
Either way, you will probably find it easier to first compute NULLABLE (that is, which non-terminals derive the empty set). There is a simple linear-time algorithm for that (linear in the size of the grammar), which again is easy to find.
If you are doing this work as part of a class, you'll probably find the relevant algorithms in your course materials. Alternatively, you can look for a copy of the Dragon book or other similar text books.
You could do like the following code:
used[i] means the rule[i] is used or not
The method is Depth-first search, see https://en.wikipedia.org/wiki/Depth-first_search
#include <iostream>
#define MAX_SIZE 1024
char rule[][10] = {
"S AC$",
"C c",
"C ;",
"A aBCd",
"A BQ",
"B bB",
"B ;",
"Q q",
"Q ;"
};
constexpr int rule_number = sizeof(rule) / sizeof(rule[0]);
char first_set[MAX_SIZE];
bool findfirst(int row, int col, int *n, bool* used) {
for (;;) {
char ch = rule[row][col];
if (ch == '$' || ch == ';' || ch == '\0') {
first_set[*n] = '\0';
break;
}
if (islower(ch)) {
first_set[(*n)++] = ch;
++col;
continue;
}
int i;
for (i = 0; i != rule_number; ++i) {
if (used[i] == true || rule[i][0] != ch)
continue;
used[i] = true;
int k = *n;
if (findfirst(i, 2, n, used) == true)
break;
used[i] = false;
*n = k;
}
if (i == rule_number)
return false;
++col;
}
return true;
}
int main() {
bool used[rule_number];
int n = 0;
for (int i = 2; rule[0][i] != '$' && rule[0][i] != '\0'; ++i) {
for (int j = 0; j != rule_number; ++j)
used[j] = false;
used[0] = true;
findfirst(0, i, &n, used);
}
std::cout << first_set << std::endl;
return 0;
}
Write a C++ program to perform addition of two hexadecimal numerals which are less than 100 digits long. Use arrays to store hexadecimal numerals as arrays of characters.the solution is to add the corresponding digits in the format of hexadecimal directly. From right to left, add one to the digit on the left if the sum of the current digits exceed 16. You should be able to handle the case when two numbers have different digits.
The correct way to get the input is to store as character array. You can either first store in a string and convert to character array, or you can use methods such as cin.getline(), getc(), cin.get() to read in the characters.
I don't know what is wrong with my program and it I don't know how to use the function getline() and eof()
char a[number1],b[number1],c[number2],h;
int m,n,p(0),q(0),k,d[number1],z[number1],s[number2],L,M;
cout<<"Input two hexadecimal numerals(both of them within 100 digits):\n";
cin.getline(a,100);
cin.getline(b,100);
int x=strlen(a) ;
int y=strlen(b);
for(int i=0;i<(x/2);i++)
{
m=x-1-i;
h=a[i];
a[i]=a[m];
a[m]=h;
}
for(int j=0;j<(y/2);j++)
{
n=y-1-j;
h=b[j];
b[j]=b[n];
b[n]=h;
}
if(x>y)
{
for(int o=0;o<x;o++)//calculate a add b
{
if(o>=(y-1))
z[o]=0;//let array b(with no character)=0
if(a[o]=='A')
d[o]=10;
else if(a[o]=='B')
d[o]=11;
else if(a[o]=='C')
d[o]=12;
else if(a[o]=='D')
d[o]=13;
else if(a[o]=='E')
d[o]=14;
else if(a[o]=='F')
d[o]=15;
else if(a[o]=='0')
d[o]=0;
else if(a[o]=='1')
d[o]=1;
else if(a[o]=='2')
d[o]=2;
else if(a[o]=='3')
d[o]=3;
else if(a[o]=='4')
d[o]=4;
else if(a[o]=='5')
d[o]=5;
else if(a[o]=='6')
d[o]=6;
else if(a[o]=='7')
d[o]=7;
else if(a[o]=='8')
d[o]=8;
else if(a[o]=='9')
d[o]=9;
if(b[o]=='A')
z[o]=10;
else if(b[o]=='B')
z[o]=11;
else if(b[o]=='C')
z[o]=12;
else if(b[o]=='D')
z[o]=13;
else if(b[o]=='E')
z[o]=14;
else if(b[o]=='F')
z[o]=15;
else if(b[o]=='0')
z[o]=0;
else if(b[o]=='1')
z[o]=1;
else if(b[o]=='2')
z[o]=2;
else if(b[o]=='3')
z[o]=3;
else if(b[o]=='4')
z[o]=4;
else if(b[o]=='5')
z[o]=5;
else if(b[o]=='6')
z[o]=6;
else if(b[o]=='7')
z[o]=7;
else if(b[o]=='8')
z[o]=8;
else if(b[o]=='9')
z[o]=9;
p=d[o]+z[o]+q;
if(p>=16)//p is the remained number
{
q=1;
p=p%16;
}
else
q=0;
if(p==0)
c[o]='0';
else if(p==1)
c[o]='1';
else if(p==2)
c[o]='2';
else if(p==3)
c[o]='3';
else if(p==4)
c[o]='4';
else if(p==5)
c[o]='5';
else if(p==6)
c[o]='6';
else if(p==7)
c[o]='7';
else if(p==8)
c[o]='8';
else if(p==9)
c[o]='9';
else if(p==10)
c[o]='A';
else if(p==11)
c[o]='B';
else if(p==12)
c[o]='C';
else if(p==13)
c[o]='D';
else if(p==14)
c[o]='E';
else if(p==15)
c[o]='F';
}
k=x+1;
if(q==1)//calculate c[k]
{
c[k]='1';
for(int f=0;f<=(k/2);f++)
{
m=k-f;
h=c[f];
c[f]=c[m];
c[m]=h;
}
}
else
{
for(int e=0;e<=(x/2);e++)
{
m=x-e;
h=c[e];
c[e]=c[m];
c[m]=h;
}
}
}
if(x=y)
{
for(int o=0;o<x;o++)//calculate a add b
{
if(a[o]=='A')
d[o]=10;
else if(a[o]=='B')
d[o]=11;
else if(a[o]=='C')
d[o]=12;
else if(a[o]=='D')
d[o]=13;
else if(a[o]=='E')
d[o]=14;
else if(a[o]=='F')
d[o]=15;
else if(a[o]=='0')
d[o]=0;
else if(a[o]=='1')
d[o]=1;
else if(a[o]=='2')
d[o]=2;
else if(a[o]=='3')
d[o]=3;
else if(a[o]=='4')
d[o]=4;
else if(a[o]=='5')
d[o]=5;
else if(a[o]=='6')
d[o]=6;
else if(a[o]=='7')
d[o]=7;
else if(a[o]=='8')
d[o]=8;
else if(a[o]=='9')
d[o]=9;
if(b[o]=='A')
z[o]=10;
else if(b[o]=='B')
z[o]=11;
else if(b[o]=='C')
z[o]=12;
else if(b[o]=='D')
z[o]=13;
else if(b[o]=='E')
z[o]=14;
else if(b[o]=='F')
z[o]=15;
else if(b[o]=='0')
z[o]=0;
else if(b[o]=='1')
z[o]=1;
else if(b[o]=='2')
z[o]=2;
else if(b[o]=='3')
z[o]=3;
else if(b[o]=='4')
z[o]=4;
else if(b[o]=='5')
z[o]=5;
else if(b[o]=='6')
z[o]=6;
else if(b[o]=='7')
z[o]=7;
else if(b[o]=='8')
z[o]=8;
else if(b[o]=='9')
z[o]=9;
p=d[o]+z[o]+q;
M=p;
if(p>=16)
{
q=1;
p=p%16;
}
else
q=0;
s[o]=p;
if(p==0)
c[o]='0';
else if(p==1)
c[o]='1';
else if(p==2)
c[o]='2';
else if(p==3)
c[o]='3';
else if(p==4)
c[o]='4';
else if(p==5)
c[o]='5';
else if(p==6)
c[o]='6';
else if(p==7)
c[o]='7';
else if(p==8)
c[o]='8';
else if(p==9)
c[o]='9';
else if(p==10)
c[o]='A';
else if(p==11)
c[o]='B';
else if(p==12)
c[o]='C';
else if(p==13)
c[o]='D';
else if(p==14)
c[o]='E';
else if(p==15)
c[o]='F';
}
k=x+1;
if(q==1)
{
c[k]='1';
for(int f=0;f<=(k/2);f++)
{
m=k-f;
h=c[f];
c[f]=c[m];
c[m]=h;
}
}
else
{
for(int e=0;e<=(x/2);e++)
{
m=x-e;
h=c[e];
c[e]=c[m];
c[m]=h;
}
}
}
Lets look at what cin.getline does:
Extracts characters from stream until end of line. After constructing
and checking the sentry object, extracts characters from *this and
stores them in successive locations of the array whose first element
is pointed to by s, until any of the following occurs (tested in the
order shown):
end of file condition occurs in the input sequence (in which case setstate(eofbit) is executed)
the next available character c is the delimiter, as determined by Traits::eq(c, delim). The delimiter is extracted (unlike basic_istream::get()) and counted towards gcount(), but is not stored.
count-1 characters have been extracted (in which case setstate(failbit) is executed).
If the function extracts no characters (e.g. if count < 1), setstate(failbit)
is executed. In any case, if count>0, it then stores a null character
CharT() into the next successive location of the array and updates
gcount().
The result of that is in all cases, s now points to a null terminated string, of at most count-1 characters.
In your usage, you have up to 99 digits, and can use strlen to count exactly how many. eof is not a character, nor it is a member function of char.
You then reverse in place the inputs, and go about your overly repetitious conversions.
However, it's much simpler to use functions, both those you write yourself and those provided by the standard.
// translate from '0' - '9', 'A' - 'F', 'a' - 'f' to 0 - 15
static std::map<char, int> hexToDec { { '0', 0 }, { '1', 1 }, ... { 'f', 15 }, { 'F', 15 } };
// translate from 0 - 15 to '0' - '9', 'A' - 'F'
static std::map<int, char> decToHex { { 0, '0' }, { 1, '1' }, ... { 15, 'F' } };
std::pair<char, bool> hex_add(char left, char right, bool carry)
{
// translate each hex "digit" and add them
int sum = hexToDec[left] + hexToDec[right];
// we have a carry from the previous sum
if (carry) { ++sum; }
// translate back to hex, and check if carry
return std::make_pair(decToHex[sum % 16], sum >= 16);
}
int main()
{
std::cout << "Input two hexadecimal numerals(both of them within 100 digits):\n";
// read two strings
std::string first, second;
std::cin >> first >> second;
// reserve enough for final carry
std::string reverse_result(std::max(first.size(), second.size()) + 1, '\0');
// traverse the strings in reverse
std::string::const_reverse_iterator fit = first.rbegin();
std::string::const_reverse_iterator sit = second.rbegin();
std::string::iterator rit = reverse_result.begin();
bool carry = false;
// while there are letters in both inputs, add (with carry) from both
for (; (fit != first.rend()) && (sit != second.rend()); ++fit, ++sit, ++rit)
{
std::tie(*rit, carry) = hex_add(*fit, *sit, carry);
}
// now add the remaining digits of first (will do nothing if second is longer)
for (; (fit != first.rend()); ++fit)
{
// we need to account for a carry in the last place
// potentially all the way up if we are adding e.g. "FFFF" to "1"
std::tie(*rit, carry) = hex_add(*fit, *rit++, carry);
}
// or add the remaining digits of second
for (; (sit != second.rend()); ++sit)
{
// we need to account for a carry in the last place
// potentially all the way up if we are adding e.g. "FFFF" to "1"
std::tie(*rit, carry) = hex_add(*sit, *rit++, carry);
}
// result has been assembled in reverse, so output it reversed
std::cout << reverse_result.reverse();
}
Regarding the text of your problem: “add one to the digit on the left if the sum of the current digits exceed 16” is wrong; it should be 15, not 16.
Regarding your code: I did not have the patience to read all your code, however:
I have noticed one long if/else. Use a switch (but you do not need one).
To find out if a character is a hex digit use isxdigit (#include <cctype>).
The user might input uppercase and lowercase characters: convert them to the same case using toupper/tolower.
To convert a hex digit to an integer:
if the digit is between ‘0’ and ‘9’ simply subtract ‘0’. This works because the codes for ‘0’, ‘1’… are 0x30, 0x31... (google ASCII codes).
if the digit is between ‘A’ and ‘F’, subtract ‘A’ and add 10.
Solving the problem:
“less than 100 digits long” This is a clear indication regarding how your data must be stored: a simple 100 long array, no std::string, no std::vector:
#define MAX_DIGITS 100
typedef int long_hex_t[MAX_DIGITS];
In other words your numbers are 100 digits wide, at most.
Decide how you store the number: least significant digit first or last? I would chose to store the least significant first. 123 is stored as {3,2,1,0,…0}
Use functions to simplify your code. You will need three functions: read, print and add:
int main()
{
long_hex_t a;
read( a );
long_hex_t b;
read( b );
long_hex_t c;
add( c, a, b );
print( c );
return 0;
}
The easiest function to write is add followed by print and read.
For read use get and putback to analyze the input stream: get extracts the next character from stream and putback is inserting it back in stream (if we do not know how to handle it).
Here it is a full solution (try it):
#include <iostream>
#include <cctype>
#define MAX_DIGITS 100
typedef int long_hex_t[MAX_DIGITS];
void add( long_hex_t c, long_hex_t a, long_hex_t b )
{
int carry = 0;
for ( int i = 0; i < MAX_DIGITS; ++i )
{
int t = a[i] + b[i] + carry;
c[i] = t % 16;
carry = t / 16;
}
}
void print( long_hex_t h )
{
//
int i;
// skip leading zeros
for ( i = MAX_DIGITS - 1; i >= 0 && h[i] == 0; --i )
;
// all zero
if ( i < 0 )
{
std::cout << '0';
return;
}
// print remaining digits
for ( i; i >= 0; --i )
std::cout << char( h[i] < 10 ? h[i] + '0' : h[i] - 10 + 'A' );
}
void read( long_hex_t h )
{
// skip ws
std::ws( std::cin );
// skip zeros
{
char c;
while ( std::cin.get( c ) && c == '0' )
;
std::cin.putback( c );
}
//
int count;
{
int i;
for ( i = 0; i < MAX_DIGITS; ++i )
{
char c;
if ( !std::cin.get( c ) )
break;
if ( !std::isxdigit( c ) )
{
std::cin.putback( c );
break;
}
c = std::toupper( c );
h[i] = c <= '9'
? ( c - '0' )
: ( c - 'A' + 10 );
}
count = i;
}
// reverse
for ( int i = 0, ri = count - 1; i < count / 2; ++i, --ri )
{
int t = h[i];
h[i] = h[ri];
h[ri] = t;
}
// fill the rest with zero
for ( int i = count; i < MAX_DIGITS; ++i )
h[i] = 0;
}
int main()
{
long_hex_t a;
read( a );
long_hex_t b;
read( b );
long_hex_t c;
add( c, a, b );
print( c );
return 0;
}
This is a long answer. Because you have much bug in your code. Your using of getline is ok. But your are calling a eof() like e.eof() which is wrong. If you have looked at your compilation error, you would see that it was complaining about calling eof() on the variable e because it is of non-class type. Simple meaning it is not an object of some class. You cannot put the dot operator . on primitive types like that. I think what you are wanting to do, is to terminate the loop when you have reached the end of line. So that index1 and index2 can get the length of the string input. If I were you, I would just use C++ builtin strlen() function for that. And in the first place, you should use C++ class string to handle strings. Also strings have a null - terminating character '\0' at the end of them. If you don't know about it, I suggest you take some time to read about strings.
Secondly, you have many bugs and errors in your code. The way you are reversing your string is not correct. Ask yourself, what are the contents of the arrays a and b at position which have higher index than the length of the string? You should use reverse() for reversing strings and arrays.
You have errors on adding loop also. Note, you are changing the arrays value when they are A, B, C, D, and so on for hexadecimal values with the corresponding decimal values 10,11,12,13 and so on. But you should change the values for the character '0' - '9' also. Because when the array holds '0' it is not integer 0. But is is ASCII '0' which has integer value of 48. And the character '1' has integer value of 49 and so on. You want to replace this values with corresponding integer values also. When you are also storing the result values in c, you are only handling only those values which are above 9 and replacing them with corresponding characters. You should also replace the integers 0 - 9 with there corresponding ASCII characters. Also don't forget to put a null terminating character at the end of the result.
Also, when p is getting larger than 15, you are only changing your carry, but you should also change p accordingly.
I believe you can reverse the result array c in a much more elegant way. By only reversing when the calculation has been performed totally. You can simple call reverse() for that.
I believe you can think hard a little bit more, and write the code in the right way. I have a few suggestions for you, don't use variable names like a,b,c,o. Try to name variables with what are they really doing. Also, you can improve your algorithm and shorten your code and headache with one simple change in the algorithm. First find the length of a and then find the length of b. If there lengths are unequal, find out which has lesser length. Then add 0s in front of it to make both lengths equal. Now, you can simply start from the back, and perform the addition. Also, you should use builtin methods like reverse() , swap() and also string class to make your life easier ;)
#include <iostream>
#include <algorithm>
#include <string>
using namespace std;
int main(){
string firstVal,secondVal;
cout<<"Input two hexadecimal numerals(both of them within 100 digits):\n";
cin >> firstVal >> secondVal;
//Adjust the length.
if(firstVal.size() < secondVal.size()){
//Find out the number of leading zeroes needed
int leading_zeroes = secondVal.size() - firstVal.size();
for(int i = 0; i < leading_zeroes; i++){
firstVal = '0' + firstVal;
}
}
else if(firstVal.size() > secondVal.size()){
int leading_zeroes = firstVal.size() - secondVal.size();
for(int i = 0; i < leading_zeroes; i++){
secondVal = '0' + secondVal;
}
}
// Now, perform addition.
string result;
int digit_a,digit_b,carry=0;
for(int i = firstVal.size()-1; i >= 0; i--){
if(firstVal[i] >= '0' && firstVal[i] <= '9') digit_a = firstVal[i] - '0';
else digit_a = firstVal[i] - 'A' + 10;
if(secondVal[i] >= '0' && secondVal[i] <= '9') digit_b = secondVal[i] - '0';
else digit_b = secondVal[i] - 'A' + 10;
int sum = digit_a + digit_b + carry;
if(sum > 15){
carry = 1;
sum = sum % 16;
}
else{
carry = 0;
}
// Convert sum to char.
char char_sum;
if(sum >= 0 && sum <= 9) char_sum = sum + '0';
else char_sum = sum - 10 + 'A';
//Append to result.
result = result + char_sum;
}
if(carry > 0) result = result + (char)(carry + '0');
//Result is in reverse order.
reverse(result.begin(),result.end());
cout << result << endl;
}
I have an array that gets populated by either a "." or a "#", and I need a way of checking whether array[y+1][x] is equal to #, do something if it is and stop the loop, otherwise increment y. First I wrote it without the & before lavirint and it gave me an error that it can't compare a pointer and an int, which got me confused cause "#" shouldn't be an int?
The problem is the first condition in the loop never happens although it should, and the loop stops when
y==n
Maybe I'm just stupid and overlooked something but I would really appreciate a solution to this.
char lavirint[500][500];
for (int i = 1; i <= n; i++)
{
for (int j = 1; j <= m; j++)
{
scanf("%c", &lavirint[i][j]);
}
}
bool n_povecava = true;
...
while(n_povecava)
{
if(&lavirint[y+1][x] == "#" || y==n)
{
k--;
m_povecava = true;
n_povecava = false;
}
else
y++;
}
"#" is a string literal of type const char[2] and decays to const char*.
You need '#' which is a character:
if (lavirint[y+1][x] == '#' || ... )
I'm a usual lurker but this is my first post! I understand you guys like detail so I will do my best. I will appreciate whatever input anyone has.
I am working on an overloading the extraction operator for an object with a dynamic array of digits. The console input will have leading white space, then an int, then anything after. I need to ignore white space, extract the int, and then leave the rest alone. Easy right?
Here is an example of code I found online:
istream & operator >> (istream &m, MyInt & p)
{
int x = 0;
p.currentLength = 0;
while ((m.peek() == '\n') || (m.peek() == '\0') ||
(m.peek() == '\t') || (m.peek() == ' '))
{
m.get();
}
while ((m.peek() >= '0') && (m.peek() <= '9'))
{
if (p.currentLength >= p.maxSize)
{
p.grow();
}
m >> p.theNumber[x];
x++;
p.currentLength++;
}
m.get();
// reverse the order (i.e. - 123 to 321)
char * temp = new char[p.maxSize];
for (int y = 0; y < p.currentLength; y++)
{
temp[y] = p.theNumber[p.currentLength - 1 - y];
}
delete [] p.theNumber;
p.theNumber = temp;
return m;
}
Now, I understand this method may work, however to me, that seems like an extremmeelly inefficient method. For a trillion digit number, Grow() would reallocate the array a trillion times! Perhaps this is not as bad as I think it is?
My current method has been using seekg() and peek() and get(). Like so:
istream& operator >> (istream& is, MyInt& z)
{
int i = 0, j = 0;
// check if next char is white
while (is.peek() == 38)
{
j++;
is.seekg(j); // skip if white
}
while (isdigit(is.peek()))
{
i++;
is.seekg(j + i);
if (!is.peek())
{
is.clear();
break;
}
}
is.seekg(j);
z.length = i;
z.digits = new int[i + 1];
for (i = 0; i < z.length; i++)
{
z.digits[i] = C2I(is.get());
}
return is;
}
Also, here is my main:
int main()
{
MyInt B;
cout << "\n\nChange B to what num? ---> ";
cin >> B;
cout << "B is now: " << B;
char c;
cout << "\n\n\n\n\nEnter char to exit : ";
cin >> c;
return 0;
}
For the life of me I can not find what is causing my program to exit. The last output seems to say, 'B is now: -1'
I believe the this means the << B failed. I have B initialized to 0 currently, and the rest of my code has presented no other issues. It's private member data only include the pointer and a length (num of digits). Also C2I() is a function that converts '0' through '9' to 0 through 9.
A big issue for me is I am fairly new to parsing, so I don't have very eloquent ways to test this, or other ideas.
Again I appreciate everything you guys do. I have already learned a great deal from browsing here!
I am trying to determine if my code is a palindrome so I created a reverse function and then a palindrome function. I am trying to assign the reversed Character array into the new function but I can't seem to get it to compile.... any tips?
Here is my palindrome function
bool Palindrome(char Characters[], unsigned long length)
{
char tempstring[62];
tempstring[62] == reverse(Characters);
for(int i=0; i <= length; i++){
if(Characters[i] == tempstring[i])
return false;
else
return true;
}
}
Here is my reverse function
void reverse(char Characters[], unsigned long length)
{
char temp;
for(int i=0; i<length/2; i++){
temp = Characters[i];
Characters[i]=Characters[length-i-1];
Characters[length-i-1]=temp;
}
}
First things first, you have a typo; == is a compare equality, =. You ought to have written
tempstring[62] = reverse(Characters);
But this will still not work. For starters, reverse is a void function and so therefore it does not return a value.
The quickest fix will be to replace that line with
reverse(Characters, length);
(Note that I'm also passing the length parameter as required).
One final thing: if you have organised your file so that reverse appears after Palindrome, then you need to forward declare reverse using this statement:
void reverse(char Characters[], unsigned long length);
That fixes the compilation errors. I defer to you to check the runtime behaviour.
You are making this quite complicated.
Just find the end of the string (strlen). Read from both ends a character at a time and if they do not match then it is not a palindrome. If the indexes become the same or they cross then you are done. It is indeed a palindrome.
I.e
bool Palindrome(char *s) {
int left = 0, right = strlen(s) - 1;
while (left < right) {
if (s[left] != s[right] return false;
++left;
--right;
}
return true;
}
EDIT
Similar vain to construct the reverse
char *Reverse(char *s)
{
char *rev = new char[strlen(s) + 1];
int left = 0, right = strlen(s) - 1;
while (right > -1) {
rev[left] = s[right];
right--;
left++;
}
rev[left] = 0;
// Remember to use delete[]
return rev;
}
EDIT 2
Or
void Reverse(char[] s, int len) {
int left = 0; right = len;
while (right > -1) {
char t = s[left];
s[left] = s[right];
s[right] = t;
left++; right--;
}
}
Then make a copy of the string, reverse it and compare it.
Your error is the line tempstring[62] == reverse(Characters);. You don't need the double = sign. In the future, it would be helpful to post the error messages you get when compiling.
bool Palindrome(char Characters[], unsigned long length)
{
char tempstring[62];
tempstring[62] = reverse(Characters);
for(int i=0; i <= length; i++){
if(Characters[i] == tempstring[i])
return false;
else
return true;
}
}
Your error is here:
tempstring[62] == reverse(Characters);
You've wrote == means, a condition that returns true or false (for example: if (5 == 7) -> false)
But what you've actually wanted to do was tempstring[62] = reverse(Characters);
One = means equal (int a = 3)
Two == means to check a condition (for example if (a == b) (and thats why you dont write in ifs: if(a = 3) because it will assign a = 3 and allways get inside the if
First of all, your reverse function returns nothing, so attempting to assign its return value to anything is not going to work:
tempstring[62] == reverse(Characters); // won't work as it is attempting to compare a void
tempstring[62] = reverse(Characters); // won't work as it is attempting to assign a void
From a more fundamental level, testing for a palindrome is much less complex than you are making it:
bool Palindrome(char Characters[], unsigned long length)
{
bool result = true;
for(int i=0; i < length / 2; i++)
{
if (Characters[i] != Characters[length - i - 1])
{
result = false;
break;
}
}
return result;
}