Error reading string with cin - c++

I have a silly mistake , but managed not find it is. On line 17 I try to read two integers and a string, but when I input (or similar):
2 3 (
I keep being asked entries. When I input (or similar):
2 3 F
reads smoothly. Could it be " ( " a special character ?
#include <iostream>
using namespace std;
int ocurs(string cad, string subcad) {
int con = -1;
size_t i = 0;
while(i != string::npos) {
i = cad.find(subcad, i);
con++;
}
return con;
}
int main() {
int n, m, con = 0;
string cad, subcad;
cin >> n >> m >> subcad;
//cout << subcad;
for(int i = 0; i < n / 2; i++)
cad.push_back('(');
for(int i = 0; i < n / 2; i++)
cad.push_back(')');
//cout << cad;
con += ocurs(cad, subcad);
cad.clear();
for(int i = 0; i < n; i++)
if(i % 2 == 0) cad.push_back('(');
else cad.push_back(')');
con += ocurs(cad, subcad);
cout << con;
return 0;
}

You end up in an endless loop inside ocurs(), because when cad.find() finds the sought substring, you feed it with the same index it returns, and it keeps finding the same substring. You need to fix your ocurs() routine, for example by adding
if (i != string::npos) ++i;
after the find statement.
The broader answer is that you should learn to use a debugger – or, at least, use some more cout statements where they might be useful.

Related

C++, Find out if a string contains a substring?

I don't know how to use the find() function to check if a string contains a substring, then the program should print out all Words, and "Contains" if Sentence contains at least one of them. Can anyone help me out? My usage of find() sets A always to true. Thanks for help
#include <iostream>
#include <string>
using namespace std;
string Words, Sentence, buf;
int i, n, j = 0;
string arr[20];
bool A;
int main() {
cout << "Words separated by slashes";
cin >> Words;
cout << "Sentence";
cin >> Sentence;
for (i = 0; i <= Words.length(); i++)
{
if (Words[i] != '/')
{
buf = buf + Words[i];
}
else
{
arr[n] = buf;
n = n + 1;
buf = "";
}
}
for (j = 0; j <= n; j++)
{
cout << arr[j] << "\n";
if (Sentence.find(arr[j]) != string::npos)
{
A = true;
}
}
if (A == true)
{
cout << "Contains.";
}
else
{
enter code herecout << "Does not contain.";
}
}
There are a few bugs and issues in this code I think, but the biggest is the for loops all go too far by one.
for (i = 0; i <= Words.length(); i++)
and
for (j = 0; j <= n; j++)
should be
for (i = 0; i < Words.length(); i++)
and
for (j = 0; j < n; j++)
The valid indexes for a string, vector or array are zero upto but not including the size of the string, vector or array.
This mistake causes the bug that you see. Suppose you have two words in arr, e.g. arr = { "stack", "overflow", "", "", ... } . Because you go around the for loop one too many times you end up searching for arr[2] which equals "". This search always succeeds because every string contains the empty string. And so you always set A to true.

Moving values in Array to the left/right to k positions?

I have an array of n values. I have a value p which can be 1 or -1. I have to move the positions in the Array k positions to the left if p = 1 or to the right if p = -1.
1 ≤ N ≤ 1.000.000
0 ≤ K ≤ 1.000.000
I tried:
#include <iostream>
using namespace std;
int main() {
int n, p, k;
int v[1000002];
cin >> n >> k >> p;
for ( int i = 1; i <= n; i++ ) {
cin >> v[i];
}
if( p == 1) {
for ( int i = k + 1; i <= n ; i++ ) {
cout << v[i] << " ";
}
for ( int i = 1; i <= k; i++ ) {
cout << v[i] << " ";
}
}
else {
for ( int i = n - k + 1; i <= n; i++ ) {
cout << v[i] << " ";
}
for ( int i = 1; i <= n - k; i++ ) {
cout << v[i] << " ";
}
}
return 0;
}
The problem is I use an online tester to do tests on it to see if it applies to all possible cases, but this solution passes all but 3 tests. The results are correct, but it says that I have surpassed the time limit for the respective test. I cannot comprehend how because I only use essential code like reading and printing the array.
I'm not sure if it will help resolve your timeouts, but I can see the following to reduce your calls a tiny bit:
After you read in n, p and k, calculate your offset.
Create a vector that is offset in size.
Read into vector until it's full.
Pipe all input directly to stdout.
Write out of the vector to stdout.
This process will reduce the readin->writeout to a single step for (n - offset elements, where offset = k or n - k depending on p).
If this still fails, you can build a stringstream and write to stringstream, and flush to cout once in a while (i.e. every 8 k or so) to reduce calls to your io channel (cout).
Sample code:
int n, p, k;
cin >> n >> k >> p;
int offset = p == 1 ? k : n - k;
std::vector tmp(offset);
std::stringstream sout;
for (size_t i = 0; i < offset; i++)
{
cin >> tmp[i];
}
for (size_t i = offset; i < n; i++)
{
cin >> sout << ' ';
if (sout.size() > _BUFFER_MAX)
{
cout << sout.str();
std::stringstream().swap(sout);
}
}
cout << sout.str();
std::stringstream().swap(sout);
for (size_t i = 0; i < tmp.size(); i++)
{
sout << tmp[i] << ' ';
if (sout.size() > _BUFFER_MAX)
{
cout << sout.str();
std::stringstream().swap(sout);
}
}
cout << sout.str();
I appreciate the way you're trying to "cheat". There will be many times in your programming career when the best plan is to provide what the customer asks for, completely ignoring the way they think you should provide it.
That enormous array at the beginning is awful, though -- you should use a std::vector with n elements, not 10000002.
I'm surprised that you are running out of time, since all the time is in I/O, and you are making the "obvious" I/O calls that will be similar to what everyone else is doing... but there are a lot of details you don't know about the test environment.
Try putting this at he start of main:
std::ios_base::sync_with_stdio(false);
See: https://en.cppreference.com/w/cpp/io/ios_base/sync_with_stdio
By default, every time you write to cout, the data is pushed into the stdout C stream. It's possible that the test environment is set up in a way the makes this slow.
If you turn off the syncing, you can use cout's internal bufferring, which will make all those little writes a lot faster in those cases.
I have managed to find the problem in my code.
Apparently the problem was that the number of positions to move could be bigger than the actual number of values. This led to some very long for's.
I feel pretty stupid , but I have learned many new things through your answers. Thank you very much!
if k is very large you can simply take it to the mod n (k%n)
you can perform placements in O(n) by calculating the final index of each element after rotation using the formulas:
(i + k) % n for right rotation and (i - k) % n for left rotation.
note: you should add an extra 'n' to handle negative modulo.
here's the code:
int v[1000001];
int main() {
int n, p, k;
cin >> n >> k >> p;
k %= n;
for (int i = 0; i < n; i++) {
if (p == -1) //right
cin >> v[(i + k) % n];
else if (p == 1) //left
cin >> v[(i - k + n) % n];
}
for (int i = 0; i < n; i++) {
cout << v[i] << " ";
}
return 0;
}

How to compare a certain character with another character of a string

In the following code, I am having trouble comparing specific letters two given strings.
#include <bits/stdc++.h>
using namespace std;
int main() {
int m, n;
cin >> m >> n;
cin.ignore();
string phrases[m];
string records[n];
for (int i = 0; i < m; i++) {
getline(cin, phrases[i]);
}
for (int i = 0; i < n; i++) {
getline(cin, records[i]);
}
int lowBound;
sort(phrases, phrases + m);
int ans = 0;
bool stillIs;
for (int i = 0; i < n; i++) {
lowBound = lower_bound(phrases, phrases + m, records[i]) - phrases;
if (lowBound == m) {
continue;
}
stillIs = true;
for (int j = 0; j < records[i].length(); i++) {
if (records[i][j] == phrases[lowBound][j]) {
stillIs = false;
}
}
if (stillIs) {
ans++;
}
}
cout << ans;
return 0;
}
On line 33, if (records[i][j] == phrases[lowBound][j]), it is not giving me an error, but if I run it with this line, nothing happens, but when I comment the if statement out, it works properly, but obviously not giving me the correct answer. Is there any way I can compare these two strings (the second one is larger in size than the first one) to find whether the first one is the start of the second one?
Thanks!
You are incrementing i instead of j in the loop at line 32
You have your test backwards in line 33 - you want to set stillIs = false if the characters don't match, (i.e., !=)
I haven't fully read your code, but those two problems jumped out at me, so see if that sorts it out

Run length encoding in C++

#include <iostream>
#include <string>
#include <vector>
using namespace std;
string compression(const string & str){
int i = str.size();
string letters;
letters[0] = str[0];
for (int j = 0; j < i; ++j){
int count = 1;
while (str[j] == str[j+1]){
count++;
j++;
}
letters.push_back('0' + count);
letters.push_back(str[j]);
}
return letters;
}
int main(){
string input;
char c;
try {
cout << "Enter the data to be compressesed: "<< endl;
cin >> input;
for (int z = 0; z < input.length(); ++z){
c = input.at(z);
}
if (!(c >= 'a' && c <= 'z')){
throw runtime_error("error: invalid input");
}
}
catch (runtime_error& excpt){
cout << excpt.what() <<endl;
return 0;
}
cout << "The compressed data is " << compression(input) << endl;
return 0;
}
The expected output is , repeated for each run of characters. Here is the amount of times is repeated in sequence.
Some examples:
aaeeeeae = 2a4e1a1e
rr44errre = invalid input
eeeeeeeeeeeeeeeeeeeee = 21e
the code works properly only if the character is repeated consecutively 9 times or less. for values of 10 and more the input is other symbols.
For example it stays blank for 10, so if input is 'aaaaaaaaaabb',output just would be 'a2b' instead of '10a2b'. For 11 its outputs ';',
so if input is 'aaaaaaaaaaabb', output is ';a2b' for some reason.
So my question is, how do i make the pushback work for all numbers and not just from 0-9?
Thank you for your time if u've gotten to here. ^^
If you can use c++11 or newer your function compression could look like:
string compression(const string & str){
int i = str.size();
string letters;
for (int j = 0; j < i; ++j){
int count = 1;
while (str[j] == str[j+1]){
count++;
j++;
}
letters += std::to_string(count);
letters.push_back(str[j]);
}
return letters;
}

A C++ program that gets 100 integers and finds the possibly given negative ones

I'm trying to write the code for a C++ program which will get some numbers (integers) and will put them into a 100 sized array, and will begin searching for possibly given negative ones (Negative of given positive numbers) after the user had inputted the sentinel number (101). For example; when we give the integers 1, 45, 12, -32, 103, 2015 and 32 to the program, it should give us the the integer 32 (because the negative form of it is existing) and if there were no numbers with this statement, then it will prints nothing. I wrote something like below; but I don't know how to do the rest... Any help or suggestions are appreciated.
I forgot to say that I use CodeBlocks 13.12 .
#include <iostream>
using namespace std;
int number = 0, nCounter = 0, sentinel = 101, i;
int myArray[100];
int main (){
cout << "Please enter your numbers: " << endl;
while ( number != 101 ){
cin >> number;
myArray[0]= number;
nCounter += 1;
}
for ( i = 0; i <= nCounter; i++ ){
if (myArray[i] > 0) // I'm stuck at here!
}
return 0;
}
Thanks and please apologize for possible English mistakes.
Here are some mistakes in the code :
First, you are assigning all the input elements to the 0th indexed element of the array.
The user can very well give 200 elements without typing 101, in that case you will overrun your array size.
A simple algorithm should be like this:
Pick the ith positive element and search through out the array for its negative.
Repeat 1 for every possible positive element in the array.
Here is a working example.
The input should be like this :
while ( (nCounter < 100) && (number != sentinel) ) {
std::cin >> number;
myArray[nCounter]= number;
nCounter += 1;
}
And the checking condition:
for ( i = 0; i < nCounter; i++ ){
if (myArray[i] > 0) {
for( j = 0; j < nCounter; j++) {
if(myArray[i] + myArray[j] == 0) // positive and negative add up to 0
std::cout << myArray[i] << std::endl ;
}
}
}
Here's a slight modification of your code that will get you what you need
#include <iostream>
using namespace std;
int number = 0, nCounter = 0, sentinel = 101, i, negMatch;
int myArray[100];
int main (){
cout << "Please enter your numbers: " << endl;
while ( number != 101 ){
cin >> number;
myArray[nCounter]= number;
nCounter += 1;
}
cout << "Enter the number to negative match";
cin >> negMatch;
for ( i = 0; i < nCounter; i++ ){
if ( (myArray[i] + negMatch) == 0) {
cout << myArray[i];
return 0;
}
}
return 0;
}
Please note the following changes:
You were inserting all the elements into the first slot, I changed it so that you enter them in the correct spot
Getting the number to be matched as input (negMatch is "32" in your question)
Modified the loop to check the numbers
However, this program is not ideal. Ideally, you would use something like Vectors, which can dynamically grow. Also, it might be better to have the user input the count of numbers, instead of using a sentinel number that he might want to give as input.
If I understand this correctly you want to print the negative ones but with positive sign. With this simple code you can do it!
#include <iostream>
using namespace std;
int number = 0, nCounter = 0, sentinel = 101;
int myArray[100];
int main (){
cout << "Please enter your numbers: " << endl;
while ( (nCounter < 100) && (number != sentinel) ) {
std::cin >> number;
myArray[nCounter]= number;
nCounter += 1;
}
for (int i = 0; i < nCounter; i++ ){
if (myArray[i] < 0) {
std::cout << (myArray[i] * -1) << std::endl ;
}
}
return 0;
}
A simple change that reduce the computational cost is the following: you can try to get information from the number given when you read it
#include <iostream>
#include <vector>
using namespace std;
int number = 0, sentinel = 101;
int main (){
cout << "Please enter your numbers: " << endl;
vector<int> array;
while (number != sentinel) {
std::cin >> number;
if(number < 0)
array.push_back(number);
}
for (int i = 0; i < array.size(); i++ )
std::cout << (array[i] * -1) << std::endl ;
return 0;
}
I suggest to write positive numbers in the beginning of the array and negative numbers in the end of the array.
Here is a demonstrative program
#include <iostream>
int main()
{
const size_t N = 100;
const int SENTINEL = 101;
int a[N];
int number;
size_t positive_end = 0;
size_t negative_begin = N;
for ( size_t i = 0; i < N && std::cin >> number && number != SENTINEL; i++ )
{
if ( number < 0 )
{
a[--negative_begin] = number;
}
else
{
a[positive_end++] = number;
}
}
if ( positive_end != 0 && negative_begin != N )
{
for ( size_t i = 0; i < positive_end; i++ )
{
size_t j = negative_begin;
while ( j != N && a[i] + a[j] != 0 ) ++j;
if ( j != N ) std::cout << a[i] << '\t' << a[j] << std::endl;
}
}
return 0;
}
If for example to enter the following sequence of numbers
1 2 -3 4 -5 6 7 3 -9 9 101
then the output will be
3 -3
9 -9
Also you could sort each part of the array (the part of positive numbers and the part of negative numbers) and apply standard algorithm std::set_intersection. In this case you could exclude situations when one negative number corresponds to several positive numbers.:)
You did not pay enough attention to the logic of your code. I'll assume you are very new at this, but no person will want to enter 100 inputs before they see what your program does.
Here is what's wrong with your code:
#include <iostream>
using namespace std;
int number = 0, nCounter = 0, sentinel = 101, i; // OK
int myArray[100]; // OK, an array with 100 elements
int main (){
cout << "Please enter your numbers: " << endl;
while ( number != 101 ){ //this is where you got it wrong
// this should have been nCounter instead of number
// If you are looking at 100 elements then the condition
// should be "nCounter != 100"
cin >> number;
myArray[0]= number; // this should have been "myArray [nCounter]=number;"
nCounter += 1;
}
for ( i = 0; i <= nCounter; i++ ){ // defining i from outer scope is unnecessary
// since it is only used in the for loop
if (myArray[i] > 0) // I'm stuck at here! // Put a semicolon here
// the remainder of the code probably here
}
return 0;
}
#include<iostream>
using namespace std;
int main()
{
//initialize size and empty array
int size = 10, x;
int myArray[10] = {};
//enter integers into array
for (int i = 0; i < size; i++)
{
cin >> myArray[i];
}
//search array for negative numbers
for (int i = 0; i < size; i++)
{
if (myArray[i] < 0)
{
x = (myArray[i] * (-1)); //multiply by -1 to get (+)
cout << x << ' ';
}
}
return 0;
}