Write a function receives a string and a character which is to be searched in the string. This function function returns the index of the search character if it exists in the array, or -1 if it does not. Also if the array contains more than one occurrence of the character, it returns the index of the left-most occurrence. For instance, if the string was ”abab” and the search character was ’b’, the function returns 1; whereas if the character was ’c’, the function returns -1.
Write the function WITHOUT using any C++ library functions.
Below is my function.
int indexOf(const char str[], char ch)
{
int search;
for (int i = 0; i<20; i++)
{
if (ch = str[i])
search ==i;
else
search =-1;
}
return search;
}
My problem is I keep getting 19(20-1) when I input either the search character or the character that doesn't exist in the array. Could anyone tell me how to modify my code to get the right answer?
if (ch = str[i]) should be if (ch == str[i]), at the moment you're just doing an assignment to ch.
And search ==i is doing a comparison, it should be search = i; so it's the opposite issue of the first.
The way I would do it is:
int indexOf(const char str[], int size, char ch)
{
for (int i = 0; i<size; i++)
{
if (str[i] == '\0')
return -1;
else if(str[i] == ch)
return i;
}
return -1;
}
The approach has the advantage of not wasting time searching in the rest of the string when it was already discovered before.
You did some mistakes. if (ch = str[i]) should be if (ch == str[i]) and search ==i; should be search =i;
And, no need to use the size of the arr if you pass a null-terminated strings.
You can try like this.
int indexOf(const char str[], char ch)
{
for (int idx = 0; str[idx]; idx++)
{
if (str[idx] == ch)
return idx;
}
return -1;
}
Related
I'm working on a problem using map.
I used multi map to have one key with multiple value to solve this problem. However, it does not work. I think the problem is when I insert elements into multimap, but I cannot find anything wrong with that code.
Here is the instruction: You will be given two words and a mapping between characters. Your task is to write a function that will check if the first word can be translated into the second word. You need to use the character mappings to decipher the first word and see if it matches the second. The character mappings can be applied repeatedly to each character.
Thank you!!
int checkmatch(char x, char y, std::multimap<char,char>mapp){
if (x == y) return 1;
while (mapp.find(x) != mapp.end()){
if(mapp.find(x)->second==y)
return 1;
else
x=mapp.find(x)->second;
}
return 0;
}
bool wordsMatch( std::vector<std::pair<char, char>> & mappings, std::string leftWord, std::string rightWord ){
// Your code goes here
std::multimap<char,char> mapp;
std::vector<char>value;
int n=mappings.size();
int result=0;
char p1[leftWord.length()], p2[rightWord.length()];
for(int i=0; i<n; i++){
mapp.insert(std::pair<char,char>(mappings[i].first, mappings[i].second));
}
if (leftWord.length() != rightWord.length()){
return false;}
for(int i=0; i<leftWord.length();i++){
p1[i]=leftWord[i];
p2[i]=rightWord[i];}
for(int i=0; i<leftWord.length();i++){
result +=checkmatch(p1[i],p2[i], mapp);
}
if (result == leftWord.length())
return true;
else
return false;
}
this is lexical analyzer code in c++ can any one explain me that code and also tell me how to read string from a file
using namespace std;
function
int isKeyword(char buffer[]){
char keywords[32][10] = {"auto","break","case","char","const","continue","default",
"do","double","else","enum","extern","float","for","goto",
"if","int","long","register","return","short","signed",
"sizeof","static","struct","switch","typedef","union",
"unsigned","void","volatile","while"};
int i, flag = 0;
what is happening here? why we use strcmp and what its used for
for(i = 0; i < 32; ++i){
if(strcmp(keywords[i], buffer) == 0){
flag = 1;
break;
}
}
return flag;
}
main
int main()
{
char ch, buffer[15];
ifstream fin("program.txt");
int j=0;
if(!fin.is_open()){
cout<<"error while opening the file\n";
exit(0);
}
while(!fin.eof()){
ch = fin.get();
what is happening here?
if(isalnum(ch))
{
buffer[j++] = ch;
}
else if((ch == ' ' || ch == '\n') && (j != 0)){
buffer[j] = '\0';
j = 0;
if(isKeyword(buffer) == 1)
cout<<buffer<<" is keyword\n";
else
cout<<buffer<<" is identifier\n";
}
}
fin.close();
return 0;
}
overall idea is to have a data structure keywords[n][m] hold all the keywords and then read a file word by word and check whether the word is in the keywords[n][m] array or not i.e. whether it is a keyword OR not.
In the main function, a file is opened and is read word by word till end and the word is passed to function iskeyword() to decide whether the word is keyword or not. Inside the iskeyword() function, we iterate through the 2-d array keywords[n][m] in a for loop and use the strcmp function to check whether the word string passed as input argument is same as an element of the 2-d array or not. If the word is in 2-d array then its a keyword and the function returns 1 and is keyword is printed on screen. Otherwise '0' is returned and 'is identifier' is output to screen.
more about strcmp here
hope this helps!
I am trying to compare two string arrays, but am not allowed to use classes or libraries to assist.
The issue I have with this is that if one string is more than one character, then it compares the whole string to again, even though it already checked the first one.
char *find_first_not_in_the_set(char *str, const char *set)
{
for(int i = 0; *(str + i) != '\0'; i++)
{
for(int j = 0; *(set + j) != '\0'; j++)
{
if(str[i] != set[j])
{
return &(str[i]);
}
}
}
return NULL;
}
If "Hello World!" is the first string and the second string is "He". The program should return l, but it returns H because it still checks the first character.
I'd rather use this:
bool matrix[256] = {0};
int length = strlen(set);
// remember all characters we have in the 'set'
for( int i=0; i<length; i++) matrix[set[i] & 0xFF] = 1;
length = strlen(str);
// now check the characters from 'str'
for( int i=0; i<length; i++) {
if( ! matrix[str[i] & 0xFF] ) {
printf( "Found: %c", str[i] );
break;
}
}
For every character in str, your code checks if it is present on each and every position in set.Thus, when i=0 'H' is compared with set[0] i.e. 'H' for j=0.But when j=1,'H' is compared with 'e' and this causes the function to return str[0] because i is still 0.
Your problem will be solved if you use just one loop and check str[i]!=set[i].
I'm tring to solve a small problem. I have two strings. s1 and s2. I want my function to return the first index of s1 that has a character not present in the string s2. This is my code.
int cad_nenhum_dos (char s1[], char s2[]){
int i,j;
for (i=0;s1[i]!='\0';i++)
{
for (j=0;s2[j]!='\0';j++)
if (s1[i]!=s2[j]) return i;
}
return -1;
}
If I run s1="hello" s2="hellm", the result should be index 4, because s1[4]='o' and "o" is not present in s2... But I allways get 0 when I run this. The -1 works fine if the strings are the same.
What am I doing wrong?
Regards
In your inner loop you need to break out when you find a character the same -- as it stands you're returning when there are any different characters in the second string, even if an earlier one was the same. You want something like
for (j=0;s2[j]!='\0';j++)
if (s1[i]==s2[j]) break;
if (s2[j]==0)
return i;
I.e. you want to return the ith character of the first string when you've made you way through the whole of the second string without having found that character.
For programming exercises at the introductory level it's a good idea to carefully execute the code manually (step through yourself and see what's happening).
As TooTone suggested, you need to break out of the loop when you find a match:
for (int i = 0; s1[i] != '\0'; i++)
{
bool charFound = false;
for (int j = 0; s2[j] != '\0'; j++)
{
if (s1[i] == s2[j])
{
charFound = true;
break;
}
}
if ( ! charFound)
return i;
}
Because the inner for-loop is comparing first letter of the first string against all the letters in the second string.
int cad_nenhum_dos (char s1[], char s2[])
{
int i,j;
for(i=0; s1[i]; i++)
{
if(s1[i] != s2[j])
return(i);
}
return(-1);
}
I need help completing this function so that it correctly returns the the number of words in the c-string. Maybe my logic is wrong ?
#include <iostream>
#include <string>
#include <cctype>
int countwords(char *, int);
using namespace std;
int main()
{
char a[] = "Four score and seven";
int size = sizeof(a)/sizeof(char);
cout << countwords(a,size);
return 0;
}
int countwords(char* a, int size){
int j = 0;
for(int i = 0; i < size; i++){
if(isspace(i) and isalnum(i - 1) and isalnum(i + 1))
j++;
}
return j;
}
You are passing the value of i to these functions instead of a[i]. That means you're testing if your loop variable is a space (for example), rather than the character at that position in the a array.
Once you have fixed that, understand that you can't blindly reference a[i-1] in that loop (because of the possibility of accessing a[-1]. You will need to update your logic (note also you must use && for logical AND, not and).
I suggest using a flag to indicate whether you are currently "inside" a word. And reset that flag whenever you decide that you are no longer inside a word. eg
int inside = 0;
for (int i = 0; i < size; i++) {
if (alnum(a[i])) {
if (!inside) {
inside = 1;
j++;
}
} else {
inside = 0;
}
}
Also, please use strlen(a) instead of sizeof(a)/sizeof(char). If you continue that practice, you're bound to have an accident one day when you try it on a pointer.
This loop is invalid
for(int i = 0; i < size; i++){
if(isspace(i) and isalnum(i - 1) and isalnum(i + 1))
First of all you does not check characters of the string whether they are spaces or alphanumeric. You check variable i whicj has nothing common with the content of the string. Moreover you have an intention to access memory beyond the array
As you are dealing with a string I would declare the function the following way
size_t countwords( const char *s );
It could be defined as
size_t countwords( const char *s )
{
size_t count = 0;
while ( *s )
{
while ( isspace( *s ) ++s;
if ( *s ) ++count;
wjile ( isalnum( *s ) ++s;
}
return ( count );
}
I do not take into account punctuation symbols. Otherwise you should substitute isspace for !isalnum.
A simpler version would be to repeatedly call strtok() on the string, and each time that an element is returned, you can increment a word count. This would take care of doubled spaces, and so on. You could even split two words with a comma but no space ("this,error") without difficulty.
something along the lines of:
do {
s = strtok(s," ,.;");
if (s) wordcount++;
} while(s);
The only immediate disadvantage is that strtok is destructive, so make a copy before starting.
To count the number of words, you merely need to count the number of times you see a non-whitespace character after a whitespace character. To get things right at the start of the string, assume there is "whitespace" to the left of the string.
int countwords(char* a, int size) {
bool prev_ws = true; // pretend like there's whitespace to the left of a[]
int words = 0;
for (int i = 0; i < size; i++) {
// Is the current character whitespace?
bool curr_ws = isspace( (unsigned char)a[i] );
// If the current character is not whitespace,
// but the previous was, it's the start of a word.
if (prev_ws && !curr_ws)
words++;
// Remember whether the current character was
// whitespace for the next iteration.
prev_ws = curr_ws;
}
return words;
}
You might also notice I included a cast to unsigned char on the call to isspace(). On some platforms, char defaults to signed, but the classifier functions isspace and friends aren't guaranteed to work with negative values. The cast forces all the values to be positive. (More details: http://en.cppreference.com/w/cpp/string/byte/isspace )