I am trying to do is display all the suffixes of a word as such:
word: house
print:
h
ho
hou
hous
house
What I did is:
#include <iostream>
#include <string.h>
using namespace std;
int main()
{
char cuvant[100];
int i,k;
cin>>cuvant;
for(i=0;i<strlen(cuvant);i++)
{
for(k=0;k<i;k++)
{
if(k==0)
{
cout<<cuvant[k]<<endl;
}else
{
for(k=1;k<=i;k++){
if(k==i) cout<<endl;
cout<<cuvant[k];
}
}
}
}
}
What am I doing wrong?
You're over-complicating it. Here's a simpler way:
#include <iostream>
#include <string>
#include <string_view>
int main() {
std::string s;
std::cin >> s;
for (std::string::size_type i = 0, size = s.size(); i != size; ++i)
std::cout << std::string_view{s.c_str(), i + 1} << '\n';
}
If you don't have access to a C++17 compiler, you can use this one:
#include <algorithm>
#include <iostream>
#include <iterator>
#include <string>
int main() {
std::string s;
std::cin >> s;
for (auto const& ch : s) {
std::copy(s.c_str(), (&ch + 1),
std::ostream_iterator<decltype(ch)>(std::cout));
std::cout << '\n';
}
}
Even so, I think it would be better for your learning progress to use a debugger to finger out the problem yourself. Here the problems with your code:
For the i=0 (the first iteration of your outer loop) the for(k=0;k<i;k++) will not be executed at all, as k<0 evaluates to false.
And having a running variable (k) that you change in two for loops that are nested, is most of the time also an indication that something is wrong.
So what you want to do: You want to create each possible prefix, so you want to create n strings with the length of 1 to n. So your first idea with the outer loop is correct. But you overcomplicate the inner part.
For the inner part, you want to print all chars from the index 0 up to i.
int main() {
char cuvant[100];
std::cin >> cuvant;
// loop over the length of the string
for (int i = 0, size = strlen(cuvant); i < size; i++) {
// print all chars from 0 upto to i (k<=0)
for (int k = 0; k <= i; k++) {
std::cout << cuvant[k];
}
// print a new line after that
std::cout << std::endl;
}
}
But instead of reinventing the wheel I would use the functions the std provides:
int main() {
std::string s;
std::cin >> s;
for (std::size_t i = 0, size = s.size(); i < size; i++) {
std::cout << s.substr(0, i + 1) << std::endl;
}
}
For this very simple string suffix task you can just use:
void main()
{
std::string s = "house";
std::string s2;
for(char c : s)
{
s2 += c;
cout << s2 << endl;
}
}
For more complicated problems you may be interested to read about Suffix Tree
Your code is wrong, the following code can fulfill your requirements
#include <iostream>
using namespace std;
int main()
{
char cuvant[100];
int i,k;
cin>>cuvant;
for(i=0;i<strlen(cuvant);i++)
{
for (k = 0; k <= i; ++k)
{
cout<<cuvant[k];
}
cout<<endl;
}
}
Related
I have a task where i need to revert a list of variable length numbers. This could be "1 2 3" or "5 6 7 8 9 10".
The sorting itself works fine.
But I can't figure out how to read the user input (with variable length) and then only execute the reverseSort once.
How can I read the user input into an array where each index is based on the space between the numbers?
Here is my code:
#include <iostream>
#include <string>
using namespace std;
bool sorted = true;
int temp;
int * arr;
int arrLength = 5;
int arrs;
// int arr = {1,2,3,4,5};
void reverseSort(int arr[], int n){
sorted = true;
for (int i = 0; i < n-1; i++){
if (arr[(i + 1)] > arr[i]){
temp = arr[i];
arr[i] = arr[i+1];
arr[i+1] = temp;
sorted = false;
}
}
if (!sorted){
reverseSort(arr,n);
}
}
int main(void){
// get user input !?!?!?!?!
cin >> arrs;
cout << arrs;
reverseSort(arr,arrLength);
for (int i = 0; i < arrLength; i++){
std::cout << arr[i] << " ";
}
return 0;
}
If you don't know number of inputs you need struct that can be resized. std::vector is good for it. For adding new data you can use member function push_back.
You can read the input line as std::string (by std::getline) and you can open new stream with read data (std::istringstream). Further one can read values from new stream.
And I think you can use std::sort instead of reverseSort (but for 'reverse' you need use std::greater as comparator).
#include <vector>
#include <iostream>
#include <fstream>
#include <sstream>
#include <string>
#include <algorithm>
int main(void){
std::vector<int> arrs;
// read only one line
std::string input;
std::getline(std::cin, input);
std::istringstream row(input);
int x;
while (row >> x)
{
arrs.push_back(x);
}
//like your reverseSort
std::sort(arrs.begin(), arrs.end(), std::greater<int>{});
for (auto var : arrs) {
std::cout << var << "; ";
}
return 0;
}
I am trying to get the numbers bigger than 4 after I loop in every other number, but the problem is that it keeps giving me bigger than 4 even tho the number isn't bigger than 4. thank you!
#include <iostream>
#include <vector>
#include <string>
using namespace std;
bool isvalidcc(const string& s)
{
vector<char> v (s.begin(), s.end());
for(auto i=0 ; i<v.size();i+=2)
{
if (v.at(i)>'4')
{
cout<<v.at(i)<<"bigger than 4"<<endl;
}
else
{
cout<<v.at(i)<<"smaller than 4"<<endl;
}
}
return false;
}
int main()
{
vector<string> cardnumbers = {
"371449635398431"
};
int i;
vector<string>::iterator itr;
for (i = 1, itr = cardnumbers.begin(); itr != cardnumbers.end(); ++itr, i++) {
// cout << i << " "
// << *itr
((isvalidcc(*itr)));
}
return 0;
}
I figured it out
Because v.at(i) is a char instead of an int it converts it into ascii code.
this means u have to convert the char in to an int the right way.
if (v.at(i) - '0' >4)
the - '0' will convert it to an int the right way otherwise it will return the wrong values, u can check this by making a new int variable and cout <<
int n = v.at(i);
cout << n;
Say the strings is "Asah1234&^%736hsi)(91",
than storage 1234,736,91 in three arrays
In general,i want to put each continuous nums in each array.
Queations: how many arrays i will need,what's the size of each group of numbers,how to make the loop.
I want to write a fuction to do it.
#include<iostream>
using namespace std;
void splitString(string str)
{
string num;
for (int i = 0; i < str.length(); i++)
{
if (isdigit(str[i]))
num.push_back(str[i]);
}
cout << num << endl;
}
int countnum( string str)
{
string num;
int sum = 0;
for (int i = 0; i < str.length(); i++)
{
if (isdigit(str[i]))
sum++;
}
cout << sum << endl;
return 0;
}
int main()
{
const int MAXLEN = 100;
char str[MAXLEN];
printf("please enter strings:");
scanf_s("%s", str, MAXLEN);
splitString(str);
countnum( str);
return 0;
}
Maybe I have a misunderstanding here. Then please comment and I will delete the answer.
This is a standard task and will be solved with a regex. It is just the definition of a variable and initialzing this variable with its range constructor. So, a one-liner.
There is no further statement needed.
Please see:
#include <iostream>
#include <string>
#include <regex>
#include <vector>
std::regex re{ R"(\d+)" };
int main() {
// The input string with test data
std::string test{"Asah123&^%736hsi)(918"};
// Define a variable numbers and use the range constructor to put all data in it
std::vector numbers(std::sregex_token_iterator(test.begin(), test.end(), re), {});
// Show the result on the screen
for (const auto& n : numbers) std::cout << n << "\n";
return 0;
}
I'm doing this exercise from DCoder, and I'm trying to solve it in C++. But I need a little help. Although I know this should be simple, I just seem to miss something.
I'm given 2 inputs, the first one is the number of letters that will follow, and the second input is these letters. I need to write a code that will give an output of the letter array in alphabetically sorted order.
Example input:
5
Z k a P b
Expected output:
a b k P Z
Can any of you guys show me what the simplest way is to solve my problem?
I tried the std::sort() function in many ways, but it's not helping me much.
Is the std::sort() function even a good way to sort something like this?
#include <iostream>
#include <string>
#include <algorithm>
#include <vector>
using namespace std;
//Compiler version g++ 6.3.0
int main() {
int n;
cin >> n;
char s;
vector<char> vec;
while (cin >> s){
vec.push_back(s);
}
sort(vec.begin(), vec.end());
for (int i = 0; i <= vec.size(); i++){
cout << vec[i] << " " ;
}
}
My code is supposed to output a c D M, but it's giving D M a c instead.
std::sort() will work fine, but note that it orders values in ascending order by default, and in ASCII uppercase letters appear before lowercase letters. To get around that, you can give std::sort() a custom comparator that performs a case-insensitive comparison, eg:
#include <iostream>
#include <string>
#include <algorithm>
#include <vector>
#include <cctype>
int main() {
int n;
char c;
std::vector<char> vec;
std::cin >> n;
for (int i = 0; (i < n) && (std::cin >> c); ++i) {
vec.push_back(c);
}
/* alternatively:
std::copy_n(std::istream_iterator<char>(std::cin), n, std::back_inserter(vec));
*/
std::sort(vec.begin(), vec.end(),
[](unsigned char c1, unsigned char c2){ return std::tolower(c1) < std::tolower(c2); }
);
for (size_t i = 0; i < vec.size(); ++i){
std::cout << vec[i] << " ";
}
/* alternatively:
for (char c : vec){
std::cout << c << " ";
}
*/
}
Live Demo
This is the code that worked for me:
#include <iostream>
#include <string>
#include <algorithm>
#include <vector>
#include <cctype>
using namespace std;
//Compiler version g++ 6.3.0
char my_tolower(char ch)
{
return static_cast<char>(tolower(static_cast<unsigned char>(ch)));
}
int main() {
int n;
cin >> n;
char c;
vector<char> vec;
for (int i = 0; (i < n) && (cin >> c); ++i){
vec.push_back(c);
}
sort(vec.begin(), vec.end(),
[](char c1, char c2){ return my_tolower(c1) < my_tolower(c2); }
);
for (auto &&c : vec){
cout << c << " ";
}
}
I have to write a short routine that will write out only upper case letters in reversed order. I managed to muster up code that somehow works, but whenever I test out my code with one specific input:
7 ENTER a b C d E f G
Instead of getting G E C I get
G (special) r E
I can't see what causes the problem, especially because it works for so many other cases. Here's the code:
#include <iostream>
using namespace std;
int main() {
int n;
cin >> n;
char stringa[n];
int length = 0;
for (int i = 0; i <= n-1; i++) {
char letter;
cin >> letter;
if (isupper (letter)) {
stringa[((n-i) - 1)] = letter;
length = length +1;
} } for ( int i =0; i<=length-1; i++) {
cout << ciag[i]
The main problem is that you are not populating your array correctly.
You are not initializing the content of the array before filling it, so it contains random garbage. Then you are filling specific elements of the array using indexes that are the directly related to each uppercase character's original position in the input, rather than the position they should appear in the output.
Since you are not initializing the array, and the input has mixed lower/upper casing, your array is going to have gaps containing random data:
stringa[0] = G
stringa[1] = <random>
stringa[2] = <random>
stringa[3] = <random>
stringa[4] = E
stringa[5] = <random>
stringa[6] = <random>
stringa[7] = <random>
stringa[8] = C
stringa[9] = <random>
stringa[10] = <random>
stringa[11] = <random>
stringa[12] = <random>
stringa[13] = <random>
stringa[14] = R
stringa[15] = E
stringa[16] = T
stringa[17] = N
stringa[18] = E
stringa[19] = <random>
stringa[20] = <random>
That is what you are seeing appear in your garbled output.
Try something more like this instead:
#include <iostream>
#include <vector>
#include <cctype>
int main()
{
int n;
std::cin >> n;
std::vector<char> stringa(n); // 'char stringa[n];' is not standard!
int length = 0;
for (int i = 0; i < n; ++i)
{
char letter;
std::cin >> letter;
if (std::isupper (letter))
{
stringa[length] = letter;
++length;
}
}
for (int i = length-1; i >= 0; --i)
{
std::cout << stringa[i];
}
return 0;
}
Or:
#include <iostream>
#include <vector>
#include <algorithm>
#include <cctype>
int main()
{
int n;
std::cin >> n;
std::vector<char> stringa(n); // 'char stringa[n];' is not standard!
int length = 0;
for (int i = 0; i < n; ++i)
{
char letter;
std::cin >> letter;
if (std::isupper (letter))
{
stringa[length] = letter;
++length;
}
}
std::reverse(stringa.begin(), stringa.begin()+length);
for (int i = 0; i < length; ++i)
{
std::cout << stringa[i];
}
return 0;
}
Both approaches produces the following array content during the first loop, and then simply output it in reverse order in the second loop:
stringa[0] = E
stringa[1] = N
stringa[2] = T
stringa[3] = E
stringa[4] = R
stringa[5] = C
stringa[6] = E
stringa[7] = G
Alternatively, I would suggest using std::getline() instead of a reading loop to obtain the user's input, and then simply manipulate the resulting std::string as needed:
#include <iostream>
#include <string>
#include <algorithm>
bool IsNotUpper(char ch)
{
return !std::isupper(ch);
}
int main()
{
std::string stringa;
std::getline(std::cin, stringa); // returns "7 ENTER a b C d E f G"
// so std::isupper() will return false for everything not in A-Z
std::setlocale(LC_ALL, "C");
stringa.erase(
std::remove_if(stringa.begin(), stringa.end(), &IsNotUpper),
stringa.end());
// returns "ENTERCEG"
std::reverse(stringa.begin(), stringa.end());
// returns "GECRETNE"
std::cout << stringa;
return 0;
}
Or, if using C++11 and later, you can use a lambda instead of a function for the std::remove_if() predicate:
#include <iostream>
#include <string>
#include <algorithm>
int main()
{
std::string stringa;
std::getline(std::cin, stringa);
std::setlocale(LC_ALL, "C");
stringa.erase(
std::remove_if(
stringa.begin(), stringa.end(),
[](char ch){return !std::isupper(ch);}
),
stringa.end());
std::reverse(stringa.begin(), stringa.end());
std::cout << stringa;
return 0;
}
Your algorithm just doesn't make any sense. You are expecting the characters to be in the array with no gaps but you skip an entry in the array when the input isn't a capital letter. Instead, put the capital letters in consecutive slots in the array in the forward direction and then traverse it in reverse order afterwards.