Finding words in sentences [closed] - c++

Closed. This question needs details or clarity. It is not currently accepting answers.
Want to improve this question? Add details and clarify the problem by editing this post.
Closed 8 years ago.
Improve this question
I have a programming assignment I cannot finish. This one part is killing me.
Accept some text from the user. Accept the string that needs to be searched. Your program is supposed to print the number of occurrences of the string found within the text, and the position at which the pattern was found. Look at the following sample output:
Sample Output:
Enter text: “Call me Ishmael. Some years ago - never mind how long precisely - having little or no money in my purse, and nothing particular to interest me on shore, I thought I would sail about a little and see the watery part of the world. It is a way I have of driving off the spleen, and regulating the circulation”
String to search – “Some years ago”
Number of occurrences – 1
Position Found – 18
This is my function:
void getText()
{
string itext, word;
int position;
bool done = false;
cout << "Enter some text" << endl;
cin >> itext;
cout << "Enter the word or phrase to wish to find" << endl;
cin >> word;
char text[itext.length()];
char search[word.length()];
for(int i = 0; i < itext.length(); i++)
{
for(int j = 0; j < word.length(); j++)
{
if(text[i] == search[j])
{
position = i;
cout << position;
}
}
}
}

This might get you started: (pseudo code from the Knuth-Morris-Pratt algorithm)
algorithm kmp_search:
input:
an array of characters, S (the text to be searched)
an array of characters, W (the word sought)
output:
an integer (the zero-based position in S at which W is found)
define variables:
an integer, m ← 0 (the beginning of the current match in S)
an integer, i ← 0 (the position of the current character in W)
an array of integers, T (the table, computed elsewhere)
while m + i < length(S) do
if W[i] = S[m + i] then
if i = length(W) - 1 then
return m
let i ← i + 1
else
if T[i] > -1 then
let m ← m + i - T[i], i ← T[i]
else
let i ← 0, m ← m + 1
(if we reach here, we have searched all of S unsuccessfully)
return the length of S
http://en.wikipedia.org/wiki/Knuth%E2%80%93Morris%E2%80%93Pratt_algorithm
EDIT:Simpler and using c++ std library :
#include <string>
#include <vector>
int main ()
{
std::string str ("There are two needles in this haystack with needles.");
std::string str2 ("needle");
// different member versions of find in the same order as above:
std::size_t found = 0;
int matches = 0;
std::vector<size_t> positions;
while( found = str.find(str2) != std::string::npos) {
matches++;
positions.push_back(found);
}
}

You can make your live much easier if you will use std::string in this task instead of char[]. All you have to do is to load your text into a std::string and then use its find method as described here:
http://www.cplusplus.com/reference/string/string/find/
By the way, I am not sure that these lines can work as you can create not dynamic array only with a constant expression length
char text[itext.length()];
char search[word.length()];

Related

How To complete string from another string [closed]

Closed. This question needs details or clarity. It is not currently accepting answers.
Want to improve this question? Add details and clarify the problem by editing this post.
Closed 1 year ago.
Improve this question
#include<iostream>
#include<string>
using namespace std;
int main ()
{
string str;
string str2;
int count;
cin>>count;
while(count!=0)
{
cin>>str;
cin>>str2;
int l=str2.length()-1;
cout<<str[0];
if(str.length()==str2.length())
{
for(int x=1;x<str.length();x++)
cout<<str2[x-1]<<(str[x]);
cout<<str2[l];
cout<<endl;
}
count--;
}
return 0;
}
Given two strings S and T. Print a new string that contains the following:
The first letter of the string S followed by the first letter of the string T.
the second letter of the string S followed by the second letter of the string T.
and so on...
In other words, the new string should be ( S0 + T0 + S1 + T1 + .... ).
Note: If the length of S is greater than the length of T then you have to add the rest of S letters at the end of the new string and vice versa.
Input
The first line contains a number N (1 ≤ N ≤ 50) the number of test cases.
Each of the N following lines contains two string S, T (1 ≤ |S|, |T| ≤ 50) consists of lower and upper English letters.
Output
For each test case, print the required string.
Example
inputCopy
2
ipAsu ccsit
ey gpt
outputCopy
icpcAssiut
egypt
in my good i get errors in some cases can someone tell me how to solve this probelm
A straightforward approach can look the following way
std::string::size_type i = 0;
for ( auto n = std::min( str.size(), str2.size() ); i < n; i++ )
{
std::cout << str[i] << str2[i];
}
while ( i < str.size() )
{
std::cout << str[i++];
}
while ( i < str2.size() )
{
std::cout << str2[i++];
}
Here is a demonstration program
#include <iostream>
#include <string>
#include <algorithm>
int main()
{
std::string str( "ipAsu" );
std::string str2( "ccsit" );
std::string::size_type i = 0;
for (auto n = std::min( str.size(), str2.size() ); i < n; i++)
{
std::cout << str[i] << str2[i];
}
while (i < str.size())
{
std::cout << str[i++];
}
while (i < str2.size())
{
std::cout << str2[i++];
}
std::cout << '\n';
}
The program output is
icpcAssiut
You could move the basic code in a separate function.
Notice the Note given above:
Note: If the length of S is greater than the length of T then you have to add the rest of S letters at the end of the new string and vice versa.
Your code runs well in terms of two same-length strings. However, cause "if(str.length()==str2.length())" in your code, your program will only output one character!
Example: given "acd" and "b", your answer is "a", but "abcd" is expected.

How do I proceed with a question like this? [closed]

Closed. This question needs to be more focused. It is not currently accepting answers.
Want to improve this question? Update the question so it focuses on one problem only by editing this post.
Closed 3 years ago.
Improve this question
Good Evening everyone. I am not really sure as to whether it is against the rules to ask questions like these on this platform (If it is, kindly tell me). The question is of a "practice competition". I could complete 5 of 10 test cases but I am not sure what is wrong in this. Please suggest any correction/logic/hint... And Time Complexity must be less than O(n^2) (According to the input given)
The approach I tried is:
int main() {
/* Enter your code here. Read input from STDIN. Print output to STDOUT */
signed long int t, n;
scanf("%d", &t);
for (int i = 1; i <= t; i++) {
int count = 0;
scanf("%d", &n);
if (n <= 10)
count = n;
else {
// count = 9;
string s;
s = to_string(n);
int len = s.length();
int x = n / (pow(10, len - 2));
int h = x / 11;
string y = to_string(x);
if (y.length() <= 2)
x = 0;
count = (9 * (len - 1)) + x + h;
}
printf("%d\n", count);
}
return 0;
}
Please suggest whatever you feel is helpful. Thank you so much.
For the problem, given that the work area you are dealing with is relatively small (the number of beautiful numbers less than 10^9 can be reasonably handled with a table of those values), here is a version of a solution that uses a pre-generated table of all of the beautiful numbers in sorted order.
Once the table is set up, it is just a matter of doing a binary search to determine the number of beautiful numbers there are that occur before the input value. The position of the closest beautiful number in the table is the number of beautiful numbers we need.
The binary search is done by utilizing the <algorithm> function std::upper_bound. This function will return an iterator to the item that is greater than the search item. Then to get the position, std::distance is used (we subtract 1, since std::upper_bound will give us the item that is greater than the searched item).
The generation of the table can be done at compile-time (by hand, just initializing an array), or if you're lazy, generated at runtime with a simple loop. Here is one such solution:
#include <algorithm>
#include <vector>
#include <iostream>
std::vector<int> values;
int generate_value(int digit, int numTimes)
{
int total = 0;
for (int i = 0; i < numTimes; ++i)
total = 10 * total + digit;
return total;
}
// I'm lazy, so let the program generate the table for me
void generate_values()
{
size_t curIdx = 0;
values.push_back(0);
for (int i = 1; i <= 9; ++i)
{
for (int j = 1; j <= 9; ++j)
values.push_back(generate_value(j, i));
}
values.push_back(1111111111);
}
// does a binary search and returns the position of the beautiful number
int beautiful(int num)
{
if (num == 0)
return 1;
// get iterator to closest number equaling the beautiful number
auto iter = std::upper_bound(values.begin(), values.end(), num);
// get distance from beginning of vector
return std::distance(values.begin(), iter) - 1;
}
int main()
{
generate_values();
std::cout << beautiful(18) << "\n";;
std::cout << beautiful(1) << "\n";;
std::cout << beautiful(9) << "\n";;
std::cout << beautiful(100500) << "\n";;
std::cout << beautiful(33) << "\n";;
std::cout << beautiful(1000000000) << "\n";;
}
Output:
10
1
9
45
12
81
The size of the table is in total, 83 entries, thus a binary search of this table will take no more than log(83) checks to find the value, which is at most 7 probes in the table.
This is not a complex problem.
Assuming your input is correct so we don’t have to do any checking we observe:
If number n is single digit the number of beautiful numbers is b = n.
If number n is double digit and the first digit is f, then the number of beautiful numbers b = 9 + x, where x is a number of all beautiful double digit numbers smaller than n,
If number n is triple digit and the first digit is f, then the number of beautiful numbers b = 2 x 9 + x, where x is a number of all beautiful triple digit numbers smaller than n.
And so on and on
Thus we can extrapolate: If number n has d digits, than the number of beautiful numbers
s = (d-1) * 9 + x,
where x is a number of beautiful d-digit numbers smaller than or equal to n.
So your problem was reduced to finding x. And this can be reduced even further. Take for instance number n = 44437. The important number here is first digit f. It is trivial to see that all 5 digit beautiful numbers that begin where single digits are less then f are ok. In our example 11111, 22222, 33333 are ok, while 444444 and larger are not.
So all you need to do is to check if beautiful number fffff is smaller than or equal to n. And this can be done with simple traversal of input string.
So your solution would be:
s = (d-1) * 9 + (f-1) + supersecretsauce,
where:
s - solution
n – your input number of age
d – number of digits, assuming your input is always correct is length(n)
f – first digit of your number n
supersecretsauce – 1 if fff…f is smaller or equal than n, 0 if bigger.
And even the traversal of input string can be optimized, but I leave that to you.
Oh yeah... and the time complexity of this solution O(n) = length(n) = log10(n).
A couple of things about the early set up.
1) From the input example you gave, it appears the t and each n need to be input sequentially, but your code prints the number of beautiful numbers before the next input is received. I would suggest reading in t first, then looping through an array of size t to get all the inputs first.
2) The constraints aren't tested. I would test the t and each value in the array mentioned before that the constraints are met, and either have the user try again if they aren't, or simply abort.

How to extract numbers used in string?

I've got a std::string number = "55353" and I want to extract the numbers that I've used in this string (5 and 3). Is there a function to do that? If so, please tell me it's name, I've been searching for quite a while now and still haven't found it...
UPD:
I've solved my problem (kinda)
std::string number(std::to_string(num));
std::string mas = "---------";
int k = 0;
for (int i = 0; i < number.size(); i++) {
char check = number[i];
for (int j = 0; j < mas.size(); j++) {
if (check == mas[j])
break;
if (check != mas[j] && check != mas[j+1]) {
mas[k] = check;
k++;
break;
}
}
}
mas.resize(k); mas.shrink_to_fit();
std::string mas will contain numbers that were used in std::string number which is a number converted to std::string using std::to_string().
Try this:
std::string test_data= "55335";
char digit_to_delete = '5';
unsigned int position = test_data.find();
test_data.erase(position, 1);
cout << "The changed string: " << test_data << "\n";
The algorithm is to find the number (as a character) within the string. The position is then used to erase the digit in the string.
Your question looks like homework, so I can guess what you forgot to tell us.
mas starts with ten -. If you spot a 5, you should replace the 6th (!) dash with a '5'. That "6th" is just an artifact of English. C++ starts to count at zero, not one. The position for zero is mas[0], the first element of the array.
The one tricky bit is to understand that characters in a string aren't numbers. The proper term for them is "(decimal) digits". And to get their numerical value, you have to subtract '0' - the character zero. So '5' - '0' == 5 - the character five minus the character zero is the number 5.

With letters represented as 2 digit numbers, converting a large number into a word

I have the following problem:
The letters a to z are represented by the numbers 10 - 35 e.g. a = 10, b = 11 ... z = 35
Given an integer how would you go about converting it into a word/sentence if each 2 digits of the number represent a letter? (the integer is the output of a decrypt process and so will always be applicable for conversion).
e.g 31232612 ---> "word"
I think that the best way to do this would be to split the integer into 2-digit chunks using % and determining the size of the number using log to the base 10? I'm unsure of exactly how this would work and I'm really interested in how other people would solve this problem.
I'm not sure whether to upload any code I have already or whether to leave it blank so in case anybody wants to give it a go from a clean slate, so just let me know.
Thanks for any feedback! (my first impression is that everything which is trivial is assumed to be homework so I thought that I would say that this isn't, I'm just doing it because I'm trying to improve and I find this kind of thing fun and thought I would share).
You will have to do something like this:
int main()
{
int numb=31231712;
std::stack<char> mystack;
int mod;
while ((mod=numb%100)!=numb){
char c=mod+88;
mystack.push(c);
numb=numb/100;
}
char c=mod+88;
mystack.push(c);
while (!mystack.empty())
{
cout << mystack.top();
mystack.pop();
}
cout << '\n';
}
It will print the word in reverse, I do not know if 88 is the right choice but that is an adjustable parameter use the ascii table. To take care of the reverse, just push all the chars in a stack. Afterwards, pop the stack till empty to get the word right.
I wrote this code, I think it can help you :)
#include <iostream>
#include <string>
#include <algorithm>
using namespace std;
int main () {
string word = "";
string integer;
cin >> integer;
for (int i = integer.size() - 1; i >= 0; i -= 2) {
int temp = integer[i] - '0';
if (i)
temp += 10 * (integer[i - 1] - '0');
word += (char)('a' + (temp - 10) + 1);
}
reverse(word.begin(), word.end());
cout << word << endl;
return 0;
}

Cant find same letters in word [closed]

Closed. This question needs details or clarity. It is not currently accepting answers.
Want to improve this question? Add details and clarify the problem by editing this post.
Closed 9 years ago.
Improve this question
can somebody give some explanation how to find same letters in word?
There is the code, but its returning whole word as same letters
int Sting::SameLetters(string word, string sk) {
string find;
find = word;
for (int i = 0; i < word.length(); i++)
{
if ((find.find(tolower(word[i])) == string::npos) &&
(sk.find(word[i]) == string::npos))
{
sk += word[i];
}
}
return sk.length();
}
So i tried to remake code and now its counting letters, but not all
int letters(string word, string sk)
{
sk = word[0];
int lenght = 0;
for ( int i =0; i <= word.length(); i++)
{
if(tolower(sk[0]) == tolower(word[i]))
{
lenght++;
}
sk = word[i];
}
return lenght;
}
My used words for test
ssabba ccea
Results
ssabba(3) ccea(2)
I have to get ssabba(6)
Think about the logic of that if statement for a while.
You initialize find to be the same as word, so when you do
find.find(tolower(word[i])) == string::npos
it will indeed find the character, and the expression will be false. And because that expression is false, due to the short-circuit nature of the logical and operator && the second check will not happen. This means that the sk += word[i] statement will never happen, and you will return the length of the unmodified sk.
I'm not exactly sure what you try to do, but that condition most definitely is not doing what you think it does.
Please have a look at the std::string::find reference. This function will search for the first occurrence in the whole string. You're iterating about all characters, so probably you just want to compare character by character to estimate the count of occurrences from a specific character? Assuming your parameter sk is a std::string with a .length() from exactly 1, you could do it like this:
size_t sameLetters(const std::string& word, const std::string& sk) {
size_t length = 0;
for (size_t i = 0; i < word.length(); i++){
if(tolower(word[i]) == tolower(sk[0]))
length++;
}
return length;
}
That would always return the number of occurrences. i.e.
sameLetters("Aaabc", "a"); /* returns 3 */
sameLetters("hello", "l"); /* returns 2 */
sameLetters("some string", "Z"); /* returns 0 */
If you tried to accomplish something different please elaborate.