Will some one explain or make a program in c++ of this for me? Got assignment but don't know how to do it.
Question: You are given a set of strings which contain only as and bs, your program should be able to check whether each string has the same number of as and bs in it or not.
e.g. The program will respond true if it get {ab, aabb, aaabbbb, bbbaaa} and say false when it gets {aab, bbba, aaabbbb}
Solve it using stack
#include <iostream>
#include <string>
#include <stack>
#include <algorithm>
using namespace std;
int count1 = 0;
int count2 = 0;
bool isInLanguageL (string w);
int main()
{
string input;
cout << "Input any string; ";
getline(cin,input);
if (input.length() % 2 != 0)
cout <<"Pattern entered does not match the language ";
else
isInLanguageL(input);
return 0;
}
bool isInLanguageL (string w)
{
stack<string> word1, word2;
string a, b;
for (unsigned i = 0; i < w.length()/2; i++)
{
a = w.at(i);
word1.push(a);
}
reverse(w.begin(), w.end());
for (unsigned i = 0; i < w.length()/2; i++)
{
b = w.at(i);
word2.push(b);
}
while(!word1.empty() && !word2.empty())
{
word1.pop();
count1 = count1++;
word2.pop();
count2 = count2++;
}
if(count1 == count2)
return true;
else
return false;
}
This solution is using stack, please refer to the comments written in the code. If you have any doubt you can comment them.
Code:
#include <iostream>
#include <stack>
#include <string>
using namespace std;
void checkString(string s) {
if (s.size() % 2 != 0) {
cout << "Doesn't satisfy the conditon\n";
return;
}
stack<char> st;
int n = s.size();
for (int i = 0; i < n; ++i) {
/*
case - 1 : If the stack is empty you can directly push the current character into the stack
case - 2 : If there are elements present in the stack, then if the current character is equal to the top character on the stack then we can push the current character
beacuse we didn't find any new character to match them.
*/
if (st.empty() || (st.top() == s[i])) {
st.push(s[i]);
}
/*
case-3 : If the stack is not emtpy and current character is different from the top character on the stack then we found a match like a-b (OR) b-a, so then we will
remove the top element from the stack and move to next character of the string
*/
else if (st.top() != s[i]) {
st.pop();
}
}
/*
case - 1 : After iterating through all the characters in the string, if we find the stack is emtpy then we can say all characters are not matched
case - 2 : If stack is emtpy, then that means all the characters are matched.
*/
(st.empty()) ? (cout << "Yes, satisfies the conditon\n") : (cout << "Doesn't satisfy the conditon\n");
}
int main() {
string s = "";
cin >> s;
checkString(s);
return 0;
}
Your solution has a number of mistakes that you should probably solve by using a debugger. Here's a reference.
This solution doesn't use a stack as you asked for, but you can write this function that uses algorithms to solve your problem:
namespace rs = std::ranges;
bool all_equal_as_and_bs(auto const & strings)
{
return rs::all_of(strings, [](auto const & string)
{
return rs::count(string, 'a') == rs::count(string, 'b');
});
}
And use it like this:
all_equal_as_and_bs(std::vector<std::string>{"ab", "aabb", "aaabbb", "bbbaaa"}); // true
all_equal_as_and_bs(std::vector<std::string>{"aab", "bba", "aaabbbb", "bbbaaa"}); // false
It should convert a string like this: Example: HEloOO, should be converted into : heLOoo . For some reason it doesn't work,it just wont convert the letters from uppercase to lowercase and vice versa any help would be appreciated ?
#include <stdio.h>
#include <string.h>
#include <ctype.h>
void rek(char array[], int d)
{
int counter=0;
if(d==0)
{
printf("%s \n",array);
printf("%d \n",counter);
}
else
{
if((array[d]>='A' && array[d]<='Z')&&(array[d-1]>='A' && array[d-1]<='Z'))
{
array[d]=array[d]+32;
array[d-1]=array[d-1]+32;
counter++;
rek(array,d-2);
}
if((array[d]>='a' && array[d]<='z')&&(array[d-1]>='a' && array[d-1]<='z'))
{
array[d]=array[d]-32;
array[d-1]=array[d-1]-32;
counter++;
rek(array,d-2);
}
}
}
int main()
{
char array[100];
int d;
gets(array);
d=strlen(array);
rek(array,d);
return 0;
}
Your function does not call itself when two adjacent characters have different cases. Also you can get different results when the string is processed from the start or from the end.
I would write the function the following way
#include <stdio.h>
#include <ctype.h>
char * rek(char *s)
{
if (s[0] && s[1])
{
size_t i = 1;
if (islower((unsigned char)s[0]) && islower((unsigned char)s[1]))
{
s[0] = toupper((unsigned char)s[0]);
s[1] = toupper((unsigned char)s[1]);
++i;
}
else if (isupper((unsigned char)s[0]) && isupper((unsigned char)s[1]))
{
s[0] = tolower((unsigned char)s[0]);
s[1] = tolower((unsigned char)s[1]);
++i;
}
rek(s + i);
}
return s;
}
int main( void )
{
char s[] = "HEloOO";
puts(rek(s));
return 0;
}
The program output is
heLOoo
The main problem is that you recur only if your have a pair of upper-case or lower-case letters. Otherwise, you drop off the end of your if, return to the calling program, and quit converting things.
The initial problem is that you've indexed your string with the length. A string with 6 characters has indices 0-5, but you've started with locations 5 and 6 -- the final 'O' and the null character.
The result is that you check 'O' and '\0'; the latter isn't alphabetic at all, so you drop through all of your logic without doing anything, return to the main program, and finish.
For future reference, Here's the debugging instrumentation I used. Also see the canonical SO debug help.
#include<stdio.h>
#include<string.h>
#include<ctype.h>
void rek(char array[], int d)
{
int counter=0;
printf("ENTER rek %s %d\n", array, d);
if(d==0)
{
printf("%s \n",array);
printf("%d \n",counter);
}
else
{
printf("TRACE 1: %d %c%c\n", d, array[d-1], array[d]);
if((array[d]>='A' && array[d]<='Z')&&(array[d-1]>='A' && array[d-1]<='Z'))
{
printf("TRACE 2: upper case");
array[d]=array[d]+32;
array[d-1]=array[d-1]+32;
counter++;
rek(array,d-2);
}
if((array[d]>='a' && array[d]<='z')&&(array[d-1]>='a' && array[d-1]<='z'))
{
printf("TRACE 3: lower case");
array[d]=array[d]-32;
array[d-1]=array[d-1]-32;
counter++;
rek(array,d-2);
}
}
}
int main()
{
char *array;
int d;
array = "HEloOO";
d=strlen(array);
rek(array,d);
printf("%s\n", array);
return 0;
}
I come up with this dirty solution:
#include <iostream>
#include <string>
#include <cctype>
using namespace std;
string solve(const string& str)
{
if (str.empty()) {
return "";
}
if (str.front() >= 'a' && str.front() <= 'z') {
return (char)toupper(str.front()) + solve(str.substr(1));
}
if (str.front() >= 'A' && str.front() <= 'Z') {
return (char)tolower(str.front()) + solve(str.substr(1));
}
}
int main()
{
string str;
cin >> str;
cout << solve(str) << endl;
return 0;
}
I'm trying to do parsing to some input string reactions read from file at formula :2W+B=8A+10Z, I'm not interested in characters i need only to split and extract the integer values to put them in a vector i.e vector associated with the reaction here is :[2 1 8 10]
i thought about many things: std::strtok(),isdigital(),find_first_of() but they all didn't work for integer values ... can any body help ??
here my try:
int main()
{
std::string input;
std::getline(std::cin, input);
std::stringstream stream(input);
while(1) {
int n;
stream >> n;
char * pch;
pch = strtok (input," ");
while (pch != NULL)
{
printf ("%s\n",pch);
pch = strtok (NULL, " ,.");
}
}
}
This will do what you want in this particular case. However, i suggest that you look into regex to parse your equation better. You may want to consider all possible cases for your input. This includes \,-,* and other operators that you may want to add in your equation. Also, I'm assuming variables in your equation has only one character.
int main()
{
string input;
getline(std::cin, input);
stringstream stream(input);
char tmp[256];
const char *in = input.c_str();
char str[256];
strcpy(str,in);
int x;
tmp[0]='\0';
char c;
vector<int> vec;
//Scan for the digit
//if it is, store the rest of the string back to str
//if it isn't, store the part of the string before a digit to tmp
while (sscanf(str,"%d%s",&x,str) || sscanf(str,"%[^0123456789]%s",tmp,str) > 1)
{
//check if tmp has the form [variable name]+[a string]
//a string can include another variable name and an operator, = in this case
while(sscanf(tmp,"%c+%[^0123456789]",&c,tmp) > 1)
vec.push_back(1);
if (tmp[0]=='\0')
vec.push_back(x);
tmp[0]='\0';
}
//just in case there're more special cases
while(sscanf(str,"%c+%[^0123456789]",&c,str) > 1)
vec.push_back(1);
for(int i = 0; i < vec.size(); i++)
cout << vec[i] << endl;
}
Output:
2
1
8
10
See comments for explanation.
EDIT
Be careful when you have a special case 2W+B=8A+10Z+C+D. Notice the last C D should both have coefficients 1. This could happen in the middle of the equation too.
Here is another solution:
#include <iostream>
#include <vector>
#include <string>
using namespace std;
int main()
{
string equ;
vector<int> digits;
cout << "enter your equation: \n";
cin >> equ;
for (auto i : equ)
{
if (isdigit(i))
{
digits.push_back(stoi(string{i}));
}
}
for (auto& i : digits)
{
cout << i << endl;
}
system("pause");
return 0;
}
You could simply do something like this, for comments see code
#include <iostream>
#include <string>
#include <vector>
std::vector<int> Split(std::string str)
{
std::vector<int> result; // will contain the different ints
// set pointer to first character in the string
char const* pch = str.c_str();
std::string digit; // buffer to keep digits if more than one
int sign = 1; // each number has a sign -1 or 1
for (; *pch; ++pch)
{
if (std::isdigit(*pch)) // if a digit, put in temp buffer
{
digit += *pch;
}
else if (std::isalpha(*pch)) // if not a digit evaluate the ones we have
{
if (digit.empty()) // none so assume 1 before letter e.g. W+2B
{
result.push_back(1*sign);
}
else
{
result.push_back(stoi(digit)*sign);
digit = "";
}
}
else // determine sign of number
{
digit = "";
if (*pch == '+')
{
sign = 1;
}
else if (*pch == '-')
{
sign = -1;
}
}
}
return result;
}
int main()
{
using namespace std;
string expr{"-2W+B=-8A+10Z"};
auto digits = Split(expr);
for (auto& digit : digits)
{
cout << digit << endl;
}
return 0;
}
I'm looking to make a method like so (which encrypts a message using Caesar Cipher, entered by the user and displays it):
void encrypt(char *message, int shift);
My code:
#include <stdio.h>
#include <conio.h>
#include <stdlib.h>
#include <string.h>
#include <ctype.h>
#include <string.h>
char num(char c)
{
const char upper_alph[26] = {'A','B','C','D','E','F','G','H','I','J','K','L','M','N','O','P','Q','R','S','T','U','V','W','X','Y','Z'};
const char lower_alph[26] = {'a','b','c','d','e','f','g','h','i','j','k','l','m','n','o','p','q','r','s','t','u','v','w','x','y','z'};
if(isupper(c)) {
for(int i = 0; i < 26; i++)
if(upper_alph[i] == c)
return i;
} else {
for(int i = 0; i < 26; i++)
if(lower_alph[i] == c)
return i;
}
return 0;
}
void encrypt(char *message, int shift)
{
int i = 0;
const char upper_alph[26] = {'A','B','C','D','E','F','G','H','I','J','K','L','M','N','O','P','Q','R','S','T','U','V','W','X','Y','Z'};
const char lower_alph[26] = {'a','b','c','d','e','f','g','h','i','j','k','l','m','n','o','p','q','r','s','t','u','v','w','x','y','z'};
while(message[i] != NULL)
{
if(isalpha(message[i]))
{
if(isupper(message[i])) {
printf("%c", upper_alph[(num(message[i])+shift)%26]);
} else {
printf("%c", lower_alph[(num(message[i])+shift)%26]);
}
} else {
printf("%c", message[i]);
}
i++;
}
}
#define OK 0
#define NO_INPUT 1
#define TOO_LONG 2
static int getLine (char *prmpt, char *buff, size_t sz) {
int ch, extra;
// Get line with buffer overrun protection.
if (prmpt != NULL) {
printf ("%s", prmpt);
fflush (stdout);
}
if (fgets (buff, sz, stdin) == NULL)
return NO_INPUT;
// If it was too long, there'll be no newline. In that case, we flush
// to end of line so that excess doesn't affect the next call.
if (buff[strlen(buff)-1] != '\n') {
extra = 0;
while (((ch = getchar()) != '\n') && (ch != EOF))
extra = 1;
return (extra == 1) ? TOO_LONG : OK;
}
// Otherwise remove newline and give string back to caller.
buff[strlen(buff)-1] = '\0';
return OK;
}
int main()
{
//reverse();
//printf("\n\n");
int rc;
char mes[1024];
int sh = 0;
rc = getLine ("Enter message to be encrypted: ", mes, sizeof(mes));
if (rc == NO_INPUT) {
// Extra NL since my system doesn't output that on EOF.
printf ("\nNo input\n");
return 1;
}
if (rc == TOO_LONG) {
printf ("Input too long [%s]\n", mes);
return 1;
}
encrypt(mes, 1);
fflush(stdin);
getchar();
return 0;
}
Thank you to anyone who helps or tries to help.
:)
EDIT: Made many corrections. Still not working :/
EDIT2: Made a lot more corrections. Getting an access violation # "while(*message != '\0')"
EDIT3: Updated the code above to the working code. Thank you everyone for your help!
One problem is you never wrap-around. Consider if you are passed something like 'Z' or 'z' with any positive shift, then you will just increment outside of the array.
You need to do something like:
upper_alph[(num(message[i])+shift)%26]
and
lower_alph[(num(message[i])+shift)%26]
You also need to allocate memory for mes:
char mes[1024];
I believe your scanf is also incorrect (c is a character, s is a string):
scanf("%s", mes);
Using %s will however only read until it gets white-space, a better option may be to read the entire line with getline().
You'll get an "index out of bounds" error on these lines:
if(isupper(message[i])) {
printf("%c", upper_alph[num(message[i])+shift]);
} else {
printf("%c", lower_alph[num(message[i])+shift]);
}
You need to calculate the index in advance and make sure it is between 0 and 25:
int shiftedIndex = (num(message[i]) + shift) % 26;
You are aware of the fact that your code only works with English as input language?
It doesn't work because you didn't allocate memory for mes:
char mes[512]; // Enough space!
Use std::string is easier:
string mes;
int sh = 0;
cout << "Enter message to be encrypted: " << endl;
getline(cin, mes);
cout << "Enter a shift amount (1-25): " << endl;
cin >> sh;
encrypt(mes, sh);
And change encrypt function to:
void encrypt(const string &message, int shift)
And keep your characters in range:
upper_alph[(num(message[i])+shift)%26]
lower_alph[(num(message[i])+shift)%26]
There is a fundamental problem here that the OP isn't understanding. And that is, to the computer, letters are just numbers. It us us humans that assign meaning to those numbers, and we can't even decide on which numbers mean what (see comments on question re ASCII, EBDIC and Unicode).
Here is a table showing how the ASCII standard maps the numbers to letters.
Notice that the character 'a' is 97, 'b' is 98, 'c' is 99 and so on. The uppercase characters start at 65 and go up from there. Note also that the letter 'a' and 'A' are on the same row! This means the bit patterns of the lower 5 bits for an upper case letter and a lower case letter are the same. Finally, as the computer only ever sees characters as numbers, it can do numeric operations on them:-
'd' - 'a' == 3
100 - 97
The second thing to note is that mathematically the Caeser cipher is just an addition with a modulo:-
encoded character = (plain text character + shift) mod 26
So now the code can written much more efficiently:-
void Encode (char *message, int shift)
{
while (*message)
{
char c = *message;
if (isalpha (c)) // check c is a letter
{
// get the letter index: this maps 'A' to 0, 'B' to 1, etc
// it also maps 'a' to 32 (97 - 65), 'b' to 33, etc
c -= 'A';
// this is 32 for lower case characters and 0 for upper case
char case_of_c = c & 32;
// map 'a' to 'A', 'b' to 'B'
c &= 31;
// the caeser shift!
c = (c + shift) % 26;
// restore the case of the letter
c |= case_of_c;
// remap the character back into the ASCII value
c += 'A';
// save the result of the shift
*message = c;
}
++message;
}
}
I have this simple problem that gets an input from the user using a function then checks if the input is 'equal' to the "password". However, strcmp would never return my desired value, and the culprit is somewhere in my loop that uses getch() to take each character separately and add them to the character array. I found this out by having printf display the character array. If I type in pass word, the function would display it as pass word ". I have no idea on why the closing double quote and a whitespace was included in the array right after the word I typed in. Any idea? Here's the code. Thanks.
#include <stdio.h>
#include <iostream>
#include <conio.h>
#include <string.h>
int validateUser();
int main()
{
for(int x = 0;x<2;x++)
{
if(validateUser())
{
system("cls");
printf("\n\n\t\t** Welcome **"); break;
}
else
{
system("cls");
printf("\n\n\t\tIntruder Alert!");
system("cls");
}
}
system("PAUSE>nul");
return 0;
}
int validateUser()
{
char password[9];
char validate[] = "pass word";
int ctr = 0, c;
printf("Enter password : ");
do
{
c = getch();
if(c == 32)
{
printf(" ");
password[ctr] = c;
}
if(c != 13 && c != 8 && c != 32 )
{
printf("*");
password[ctr] = c;
}
c++;
}while(c != 13);
return (!strcmp(password, validate));
}
Your char array password does not
have a terminating null char.
You need to ensure that you don't
stuff more than 8 char into
password
Also c++ should be ctr++
.
do {
// stuff char into password.
ctr++;
}while(c != 13 && ctr <8);
password[ctr] = 0;
You're incrementing c in your loop. You should be incrementing ctr. Also, all the stuff everyone else has said (null terminator, only 8 characters, etc).
getch() is a function defined in a non-standard header <conio.h>. Relying on non-standard features is not recommended when you want your code to be portable. :)
do {
// stuff char into password.
++ctr;
} while(c != 13 && ctr < 9);
password[ctr] = '\0';