How to insert one key and multiple value in multimap c++ - c++

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;
}

Related

Tips for optimizing identification of `k` consecutive equal characters

I am trying to solve a question:
An operation consists of selecting k consecutive equal characters and removing them. This operation is to be performed as long as possible. Return the final word after all the operations have been performed. For e.g., for abbcccb and k=3, the output should be a.
The code that I could come up with is as follows:
#include<iostream>
#include<string>
#include<unordered_set>
using namespace std;
string helper(string& s, int k) {
if(s.size()<k) return s;
string str;
for(int i=0; i<s.size(); i++){
char currChar=s[i];
int j=i+1, count=0;
while(j<s.size() && count<=k && s[j]==currChar) {
j++;
count++;
}
if(j-i==k) {
for(int k=0; k<i; k++) str.push_back(s[k]);
for(int k=j; k<s.size(); k++) str.push_back(s[k]);
break;
}
}
if(str.empty()) return s;
return helper(str, k);
}
int main() {
// string s="abbcccb";
// string s="abcdef";
// string s="baac";
string s="aba";
cout<<helper(s, 2);
return 0;
}
Working code here.
However, I think there is a possible way to optimize the code further, especially the part where I determine if k consecutive characters are equal.
Could someone please provide few pointers/ideas/solution?
Thanks.
This is a standard problem that can be solved using stack in O(n) time. Full explanation is already given on this site. Please refer this Reduce the string by removing K consecutive identical characters

How do I get the right index of the string character?

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;
}

Partial string search in C++

Let's say I have a vector of strings called info that reads names of websites from a file one by one sequentially.
This is what I have that searches for names, by the complete name only:
int linearSearch(vector <string> inputs, string search_key){
for (int x=0; x<inputs.size(); x++){
if (search_key==inputs[x]){
return x;
}
}
return -1;
}
Now what if I wanted to COUNT the amount of websites with a particular word in it?
So if I had
apple.com
mac.com
macapple.com
applepie.com
potato.com
and I searched for "apple", it would return 3.
You can use string::find to perform a partial search of the string and store the value into a size_t variable.
Compare that to std::string::npos and increment count if they are not equal.
Here is an simple example using arrays not vector so you can learn and make modifications as required.
int main() {
string inputs[2] = {"stack overflow", "stack exchange"};
string search_key = "stack";
int count;
for(int i = 0; i <sizeof(inputs)/sizeof(inputs[0]); i++)
{
//npos returns -1. If substring is not found, find will return -1.
//if substring is found, condition fails and count is incremented
if (inputs[i].find(search_key) != string::npos)
count++;
}
cout << count;
return 0;
}
Here is the link for the code above. You can see that the output is 2 as expected as the word stack occurs twice in the inputs array.

Code not returning the right index

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);
}

Getting Word Frequency From Vector In c++

I have googled this question and couldn't find an answer that worked with my code so i wrote this to get the frequency of the words the only issue is that i am getting the wrong number of occurrences of words apart form one that i think is a fluke. Also i am checking to see if a word has already been entered into the vector so i don't count the same word twice.
fileSize = textFile.size();
vector<wordFrequency> words (fileSize);
int index = 0;
for(int i = 0; i <= fileSize - 1; i++)
{
for(int j = 0; j < fileSize - 1; j++)
{
if(string::npos != textFile[i].find(textFile[j]) && words[i].Word != textFile[j])
{
words[j].Word = textFile[i];
words[j].Times = index++;
}
}
index = 0;
}
Any help would be appreciated.
Consider using a std::map<std::string,int> instead. The map class will handle ensuring that you don't have any duplicates.
Using an associative container:
typedef std::unordered_map<std::string, unsigned> WordFrequencies;
WordFrequencies count(std::vector<std::string> const& words) {
WordFrequencies wf;
for (std::string const& word: words) {
wf[word] += 1;
}
return wf;
}
It is hard to get simpler...
Note: you can replace unordered_map with map if you want the worlds sorted alphabetically, and you can write custom comparisons operations to treat them case-insensitively.
try this code instead if you do not want to use a map container..
struct wordFreq{
string word;
int count;
wordFreq(string str, int c):word(str),count(c){}
};
vector<wordFreq> words;
int ffind(vector<wordFreq>::iterator i, vector<wordFreq>::iterator j, string s)
{
for(;i<j;i++){
if((*i).word == s)
return 1;
}
return 0;
}
Code for finding the no of occurrences in a textfile vector is then:
for(int i=0; i< textfile.size();i++){
if(ffind(words.begin(),words.end(),textfile[i])) // Check whether word already checked for, if so move to the next one, i.e. avoid repetitions
continue;
words.push_back(wordFreq(textfile[i],1)); // Add the word to vector as it was not checked before and set its count to 1
for(int j = i+1;j<textfile.size();j++){ // find possible duplicates of textfile[i]
if(file[j] == (*(words.end()-1)).word)
(*(words.end()-1)).count++;
}
}