Is there a way to do a character/string restriction? - c++11

//The idea is, how to restrict the user to these specific symbols? p.s in the num_1/2 iput as: 10 is valid asd10 not valid
do
{
//Input
cout << "Enter first the arithmatic operation (+, -, *, /, %) and then both operands: "; cin >> operation; cin >> num_1; cin>> num_2;
if (cin.fail()) {
cin.clear();
cin.ignore(std::numeric_limits<std::streamsize>::max(), '\n');
continue;
}
} while ( (operation != '+' && operation != '-' && operation != '*' && operation != '/' && operation != '%' )
&& ((num_1 <= '0' || num_1 <= '9') || (num_1 >= 'A' && num_1 <= 'F'))
&& ((num_2 >= '0' && num_2 <= '9') || (num_2 >= 'A' && num_2 <= 'F')) );

The standard library gives you almost no control over this stuff.
It's an oldie, but readline is my still my goto for whenever I need a fancy input:
#include <cstdio>
#include <cstdlib>
#include <readline/readline.h>
int snuff_key(int, int) { return 0; }
bool is_key_allowed(char c) {
return (c >= '0' && c <= '9')
|| (c >= 'A' && c <= 'F')
|| (c == '*')
|| (c == '/')
|| (c == '+')
|| (c == '-');
}
int main() {
char* buf;
rl_initialize();
for (unsigned char c = 0; c < 128; c++) {
if (!(is_key_allowed(c))) {
rl_bind_key(c, snuff_key);
}
}
if ((buf = readline("")) != nullptr) {
printf("you typed: '%s'\n", buf);
free(buf);
}
return 0;
}

Related

Near-Neighbor Searching in Ternary Search Tree

How is the search for the nearest neighbors in the tree? Trying to find information, I get only some formulas without illustrative examples.
enter image description here
Example of a function:
void nearsearch(Tptr p, char *s, int d)
{ if (!p || d < 0) return;
if (d > 0 || *s < p->splitchar)
nearsearch(p->lokid, s, d);
if (p->splitchar == 0) {
if ((int) strlen(s) <= d)
srcharr[srchtop++] = (char *) p->eqkid;
} else
nearsearch(p->eqkid, *s ? s+1:s,
(*s == p->splitchar) ? d:d-1);
if (d > 0 || *s > p->splitchar)
nearsearch(p->hikid, s, d);
}

how to find number of words in a sentence in a string?

How would I find the number of words in a sentence when the sentence has uneven spacing, for example:
"how are you?"
Here is my code below, but I'm not getting the expected output.
#include <iostream>
#include <string>
using namespace std;
int main() {
string s = "how are you?";
int vowels = 0;
int consonants = 0;
int words = 1;
for(int i= 0; i < s.length(); i++) {
if(s[i] == 'A' || s[i] == 'E' || s[i] == 'I' || s[i] == 'O' || s[i] == 'U' || s[i] == 'a' || s[i] == 'e' || s[i] == 'i' || s[i] == 'o' || s[i] == 'u') {
vowels+=1;
} else if((s[i] == ' ') {
words +=1;
} else if ((s[i] == ' ')) {
words += 1;
} else {
consonants += 1;
}
}
cout << "number of vowels "<< vowels<< endl;
cout << "number of words "<< words << endl;
cout << "number of consonants "<< consonants << endl;
return 0;
}
Here below is an updated version of your code :
#include <iostream>
#include <sstream>
#include <vector>
using namespace std;
int
main() {
string s = "how are you?";
int vowels = 0;
int consonants = 0;
int words = 0;
std::string buf;
std::stringstream ss(s);
std::vector < std::string > tokens;
while (ss >> buf) {
words++;
for (int i = 0; i < buf.length(); i++) {
if (buf[i] == 'A' || buf[i] == 'E' || buf[i] == 'I' || buf[i] == 'O' ||
buf[i] == 'U' || buf[i] == 'a' || buf[i] == 'e' ||
buf[i] == 'i' || buf[i] == 'o' || buf[i] == 'u') {
vowels++;
} else {
consonants++;
}
}
}
cout << "number of vowels " << vowels << endl;
cout << "number of words " << words << endl;
cout << "number of consonants " << consonants << endl;
return 0;
}
(PS: you might want to modify the code so that characters like "?" does not count as a word)
You can also check other solutions using Boost library : link
You can do something like this:
int main() {
string s = "how are you?";
int vowels = 0;
int consonants = 0;
int words = 0;
for(int i= 0; i < s.length(); i++) {
if(s[i] == 'A' || s[i] == 'E' || s[i] == 'I' || s[i] == 'O' || s[i] == 'U' || s[i] == 'a' || s[i] == 'e' || s[i] == 'i' || s[i] == 'o' || s[i] == 'u') {
vowels+=1;
} else if((s[i] == ' ') {
words +=1;
} else if (word == 0 || (i > 0 && s[i] != ' ' && s[i-1] == ' ')) {
words += 1;
} else {
consonants += 1;
}
}
cout << "number of vowels "<< vowels<< endl;
cout << "number of words "<< words << endl;
cout << "number of consonants "<< consonants << endl;
return 0;
}
You can simply use a boolean flag to keep track if a word is found. when a space or any other punctuation( or non-alphabets or digits) occurs simply check if the flag is true or false, if the flag is true then increment the word count.
The modified code will look something like this,
#include <iostream>
#include <string>
using namespace std;
int main() {
string s = "how are you?";
int vowels = 0;
int consonants = 0;
int words = 0;
bool wordFound=false;
for(int i= 0; i < s.length(); i++) {
if(s[i] == 'A' || s[i] == 'E' || s[i] == 'I' || s[i] == 'O' || s[i] == 'U' || s[i] == 'a' || s[i] == 'e' || s[i] == 'i' || s[i] == 'o' || s[i] == 'u') {
vowels+=1;
wordFound=true;
} else if (!((s[i]>='A' && s[i]<='Z') || (s[i]>='a' && s[i]<='z') || (s[i]>='0' && s[i]<='9'))) {
if(wordFound)
{
words+=1;
}
wordFound=false;
} else {
wordFound=true;
consonants += 1;
}
}
if(wordFound)words+=1;
cout << "number of vowels "<< vowels<< endl;
cout << "number of words "<< words << endl;
cout << "number of consonants "<< consonants << endl;
return 0;
}
C++ 11 has a regular expression library in the standard. So, unless you want to "do it by hand", you could just use <regex> header file.
#include <iostream>
#include <cinttypes>
#include <string>
#include <regex>
int main(int argc, const char* argv[]) {
std::regex words("\\w+");
std::string input("how are you?");
size_t nwords = 0;
for (auto iter = std::sregex_iterator(input.begin(),
input.end(),
words);
iter != std::sregex_iterator();
++iter) {
std::cout << (*iter).str() << std::endl;
nwords++;
}
std::cout << nwords << std::endl;
return 0;
}
If you do want to code this by hand, it might be easiest to think about the problem in terms of finite state machines.
There are 2 states: {IN_WORD, IN_SPACES}. The current character in your iteration defines the current state.
When in state IN_WORD, you collect the characters into a string.
When in state IN_SPACES, you just skip the character.
On a transition from IN_WORD -> IN_SPACES, a word is done and you increase your word counter.
If you are in state IN_WORD when the iteration is done (past last character), you need to increase your word counter as well.
#include <iostream>
#include <cinttypes>
#include <string>
#include <regex>
#include <cctype>
size_t manual_word_counter( const std::string& input) {
if (input.empty()) // empty string is easy...
return UINTMAX_C(0);
enum State { IN_WORD, IN_SPACES };
size_t index = UINTMAX_C(0);
auto determine_state = [&input, &index] () -> State {
auto c = input[index];
if (std::isspace(c) || std::ispunct(c))
return IN_SPACES;
return IN_WORD;
};
size_t counter = UINTMAX_C(0);
State currentState = determine_state();
for (index = 1; index < input.size(); index++) {
State newState = determine_state();
if (currentState == IN_WORD && newState == IN_SPACES)
counter++;
currentState = newState;
}
if (currentState == IN_WORD)
counter++;
return counter;
}
int main(int argc, const char* argv[]) {
std::regex words("\\w+");
std::string input("how are you?");
size_t nwords = 0;
for (auto iter = std::sregex_iterator(input.begin(),
input.end(),
words);
iter != std::sregex_iterator();
++iter) {
std::cout << (*iter).str() << std::endl;
nwords++;
}
std::cout << nwords << std::endl;
std::cout
<< "manual solution yields: "
<< manual_word_counter(input) << " words." << std::endl;
return 0;
}

Unable to compare pointes and integeres in c++14

I'm trying to program a code decoder. But I get the following error for all the comparisons in the if statements:
'error: ISO C++ forbids comparison between pointer and integer
[-fpermissive]'
The examples for the input string are ".-.--" and "-..-.--".
#include <iostream>
#include <string>
using namespace std;
int main() {
string s;
int c[100], t = 0, l, i = 0;
l = s.length();
cin >> s;
if (s[0] == '.') {
c[0] = 0;
t += 1;
while (i < l) {
if (s[i] == '-' && s[i + 1] == '.') {
c[t] = 1;
t += 1;
i += 2;
}
if (s[i] == '.') {
c[t] = 0;
t += 1;
i++;
}
if (s[i] == '-' && s[i + 1] == '-') {
c[t] = 2;
t += 1;
i += 2;
}
}
}
if (s[0] == '-' && s[1] == '.') {
c[0] = 1;
t += 1;
while (i < l) {
if (s[i] == '-' && s[i + 1] == '.'
'){
c[t] = 1; t += 1; i += 2;
}
if (s[i] == '.') {
c[t] = 0;
t += 1;
i++;
}
if (s[i] == '-' && s[i + 1] == '-') {
c[t] = 2;
t += 1;
i += 2;
}
}
}
if (s[0] == '-' && s[1] == '-') {
c[0] = 2;
t += 1;
while (i < l) {
if (s[i] == '-' && s[i + 1] == '.') {
c[t] = 1;
t += 1;
i += 2;
}
if (s[i] == ".") {
c[t] = 0;
t += 1;
i++;
}
if (s[i] == "-" && s[i + 1] == "-") {
c[t] = 2;
t += 1;
i += 2;
}
}
}
for (i = 0; i < t; i++) {
cout << s[t];
}
return 0;
}
How do I resolve this issue?
You were using single quotes until you got here:
if(s[i]=="-"&&s[i+1]=="-"){
You need to change it to single quotes so you have an int to int comparison.
if(s[i]=='-'&&s[i+1]=='-'){
When you say
"-"
you are creating a pointer.
When you say
'='
you are creating an int.
(" ") is a string literal which is char const * which is a pointer and (' ') is char which get promoted to int, so you can't compare them. They must be type compatible.

How to step over a recursive call while debugging?

I have tried in two IDEs namely Clion and Xcode and I get the same results.
The debugger steps into isMatch function again even if I use stepOver. I've successfully used 'stepOver' in case of other functions but I'm not sure if it works the expected way for recursive calls. Can someone help me with this?
bool isMatch(string s, string p) {
//Base case
if(s.length() == 0 && p.length() == 0)
return true;
else if(p[1] == '*') {
int i = 0;
for (; (s[i] == p[0] || p[0] == '.') && i<s.length() ; i++) {
string temp1 = s.substr(i);
string temp2 = !p.length()? "" : p.substr(2);
if (isMatch(temp1, temp2))
return true;
}
if( isMatch(s.substr(i), !p.length()? "" : p.substr(2) ))
return true;
return false;
}
else
return (s[0] == p[0] || p[0] == '.') && isMatch(s.substr(1), p.substr(1));
}

Find text path through character matrix with recursive algorithm

I'm trying to solve this question: http://www.spoj.com/problems/ALLIZWEL/
Find whether there is a path in the given matrix which makes the
sentence “ALL IZZ WELL”.
There is a path from any cell to all its neighbouring cells.
A neighbour may share an edge or a corner.
Input Specification:
The first line consists of an integer t representing the number of test cases.
The first line of each test
case consists of two integers R and C representing the number of rows and number of columns in the matrix.
Output Specification:
For each test case print “YES” if there is a path which makes the sentence “ALLIZZWELL”.
Else print “NO”.
For sample test cases, open the link.
My code:
#include <iostream>
#include <map>
#include <vector>
#include <string>
#include <utility>
#include <algorithm>
#include <stack>
#include <queue>
#include <climits>
#include <set>
using namespace std;
char matrix[101][101];
bool var;
int r,c;
bool check (string str,int pos, bool visited[101][101],int i, int j);
int main (void)
{
int t,i,j;
cin>>t;
bool ans;
while (t != 0)
{
int r,c,flag=0;
cin>>r>>c;
for ( i = 0; i < r; i++ )
{
for ( j = 0; j < c; j++ )
{
cin>>matrix[i][j];
}
}
string str = "ALLIZZWELL";
int pos = 1;
for ( i = 0; i < r; i++ )
{
for ( j = 0; j < c; j++ )
{
bool visited[101][101];
for ( i = 0; i < 101; i++ )
for ( j = 0; j < 101; j++ )
visited[i][j] = false;
visited[i][j] = true;
if (matrix[i][j] == 'A') // for all possible starting positions
ans = check(str,pos,visited,i,j);
if (ans == true)
{
cout<<"YES\n";
flag = 1;
break;
}
if (flag == 1)
break;
}
}
if (flag == 0)
cout<<"NO\n";
t--;
}
return 0;
}
bool check (string str,int pos, bool visited[101][101],int i, int j) // checking for all possible test cases
{
bool result = false;
if (pos == str.length() + 1)
return true;
if (i+1 < r && visited[i+1][j] != true && matrix[i+1][j] == str[pos])
{
visited[i+1][j] = true;
result = result || check(str,pos+1,visited,i+1,j);
if (result == false)
visited[i+1][j] = false;
}
else if (i-1 >= 0 && visited[i-1][j] != true && matrix[i-1][j] == str[pos])
{
visited[i-1][j] = true;
result = result || check(str,pos+1,visited,i-1,j);
if (result == false)
visited[i-1][j] = true;
}
else if (j+1 < c && visited[i][j+1] != true && matrix[i][j+1] == str[pos])
{
visited[i][j+1] = true;
result = result || check(str,pos+1,visited,i,j+1);
if (result == false)
visited[i][j+1] = true;
}
else if (j-1 >= 0 && visited[i][j-1] != true && matrix[i][j-1] == str[pos])
{
visited[i][j-1] = true;
result = result || check(str,pos+1,visited,i,j-1);
if (result == false)
visited[i][j-1] = true;
}
else if (i+1 < r && j+1 < c && visited[i+1][j+1] != true && matrix[i+1][j+1] == str[pos])
{
visited[i+1][j+1] = true;
result = result || check(str,pos+1,visited,i+1,j+1);
if (result == false)
visited[i+1][j+1] = true;
}
else if (i+1 < r && j-1 >= 0 && visited[i+1][j-1] != true && matrix[i+1][j-1] == str[pos])
{
visited[i+1][j-1] = true;
result = result || check(str,pos+1,visited,i+1,j-1);
if (result == false)
visited[i+1][j-1] = true;
}
else if (i-1 >= 0 && j+1 < c && visited[i-1][j+1] != true && matrix[i-1][j+1] == str[pos])
{
visited[i-1][j+1] = true;
result = result || check(str,pos+1,visited,i-1,j+1);
if (result == false)
visited[i-1][j+1] = true;
}
else if (i-1 >= 0 && j-1 >= 0 && visited[i-1][j-1]!= true && matrix[i-1][j-1] == str[pos])
{
visited[i-1][j-1] = true;
result = result || check(str,pos+1,visited,i-1,j-1);
if (result == false)
visited[i-1][j-1] = true;
}
return false;
}
The code is quite self-explanatory: I am trying all possible cases.
I am getting a WA in the third test case, i.e.
2 9
A.L.Z.E..
.L.I.W.L.
I tried debugging but I couldn't narrow down my problem.
The main problems are:
Using i and j in the loop clearing visited (as well as the outer loops)
Using r and c as global variables in check, but writing them as local variables in main
Always returning false from check (instead of result)
Only trying the first choice in check (turn "else if" into "if")
Not clearing the value in ans
Only breaking out of the inner loop, not both the i and j loop
Terminating the search when pos gets to str.length()+1 instead of str.length()
It often helps to put some print statements in recursive functions like these, try them out on a simple example, and see whether the sequence of calls matches your expectations.

Resources