I want to write a for loop that passes the strings for 0 till 9:
for (string j = "0"; j < "10"; j++) {
}
but it doesn't know the operator ++ (it gets an integer (1) and not a string "1").
I think to write: j+="1", but then j will be "01" and then "011"...
p.s. I don't want to use functions of #include <string> or something else. (stoi, etc)
any help appreciated!
Loop with integers, then manually convert it to a string?
Like
for (int i = 0; i < 10; i++)
{
string j(1, '0' + i); // Only works for single digit numbers
}
Do your iterations with integers, and convert them to strings inside the loop, like this:
// Your loop counter is of type int
for (int i = 0 ; i != 10 ; i++) {
// Use string stream to convert it to string
ostringstream oss;
oss << i;
// si is a string representation of i
string si = oss.str();
cout << si << endl;
}
This works for any kind of integers without limitations.
Here is a short demo.
Not that way, but...
char x[]={'0',0};
for(; x[0] <= '9'; ++x[0])
{
}
Edit: 0..99 version
char x[]={'0','0',0};
int stroffs = 1;
for(; x[0] <= '9'; ++x[0])
{
for(x[1] = '0'; x[1] <= '9'; ++x[1])
{
char * real_str = x + stroffs;
}
stroffs = 0;
}
You can do like j[0]++ to increase first char to next ascii value. but this is only for '0'-'9'
edit: Just an idea, not a perfect code: for 0 to 20;
i = 0;
(j > "9") && (i==0) ? j[i]++ : (++i, j="10");
With your constraints (although I have no idea how you use string without #include <string>):
const char* x[] =
{
"0", "1", .... , "10"
}
for ( int i = 0 ; i <= 10 ; i++ )
{
x[i]....
}
you can use atoi with:
#include <stdlib.h> // or #include <cstdlib>
for (int j = atd::atoi("0"); j < std::atoi("10"); j++) {
}
Related
I know it is possible to use n nested for loops to get the result. This however isn't very flexible. If I wanted to get every string of n+2 characters I would have to write an extra two for loops.
I'm pretty sure I should use a parameter called n_Letters and use some kind of recursion. Any ideas? This is how my code looks right now. It gives all the 3 character combinations.
#include <iostream>
#include <string>
using namespace std;
void StringMaker(){
for(int firstLetter = 97; firstLetter < 123; firstLetter++){
char a = firstLetter;
for(int secondLetter = 97; secondLetter < 123; secondLetter++){
char b = secondLetter;
for(int thirdLetter = 97; thirdLetter < 123; thirdLetter++){
char c = thirdLetter;
cout << a << b << c << endl;
}
}
}
}
int main() {
StringMaker(); // I could add a parameter n_Letters here
}
This is a simple tree traversal problem that can easily be solved using recursion. Using a counter (count) and accumulator (partial) recur on your function for each letter until count is zero then print partial.
#include <iostream>
#include <string>
void StringMaker(int count, std::string partial = "") {
if (count == 0) {
std::cout << partial << '\n';
}
else {
for (char letter = 'a'; letter <= 'z'; ++letter) {
StringMaker(count - 1, partial + letter);
}
}
}
int main() {
StringMaker(3);
return 0;
}
Edit: It seems their are some concerns with my answer regarding memory allocations. If it's a concern for you, consider this alternative solution. Increment the first character if it isn't 'z', otherwise set it to a and repeat with the the second character. Do this until the last character is set from z to a. This acts as a sort of base 26 counter with count digits.
#include <iostream>
#include <string>
void StringMaker(size_t count)
{
std::string data(count, 'a');
size_t i = 0;
do
{
std::cout << data << '\n';
for (i = 0; i < count; ++i)
{
auto & next_char = data[i];
if (next_char < 'z') {
++next_char;
break;
}
else {
next_char = 'a';
}
}
} while (i != count);
}
int main() {
StringMaker(3);
return 0;
}
Here is my just-for-fun solution:
void StringMaker(int n)
{
int base = ('z' - 'a' + 1);
std::string str(n, '\0');
for(int i = 0; i < int_pow(base, n); ++i)
{
for(int j = 0; j < n; ++j)
{
str[n - j - 1] = 'a' + i / int_pow(base, j) % base;
}
cout << str << '\n';
}
}
Suppose we have i written in numerical system with base 26 (from a to z), so increment i with n = 4 give us aaaa, aaab and so on
I have the following string:
char *str = "test";
I need to generate distinct entries from it using dots, e.g. the following would be generated:
test
t.est
te.st
tes.t
t.e.s.t
t.e.st
te.s.t
...
Note: cannot have a dot at the start nor at the end.
What I have currently is able to generate some of them, but not all, I tried multiple things, such as:
1. On the bit level (dot on and off for each iteration) which sounded like the most reasonable to date, but I had an obstacle.
2. Just a nested loop which would generate based on equality, e.g. (x, y, and compare x, y with i (where i would serve as the loop for generating the new string).
Current code I have:
#include <stdio.h>
#include <string.h>
int main() {
char str[] = "test";
for (int k = 0; k < sizeof(str) - 1; ++k) {
for (int x = k; x < sizeof(str) - 1; ++x) {
for (int y = x + 1; y < sizeof(str) - 1; ++y) {
char tmp[512], *p = tmp;
for (int i = 0; i < sizeof(str); ++i) {
*p++ = str[i];
if (i == x || i == y)
*p++ = '.';
}
*p++ = '\0';
printf("%s\n", tmp);
}
}
}
return 0;
}
This gives:
t.e.st
t.es.t
t.est.
te.s.t
te.st.
tes.t.
te.s.t
te.st.
tes.t.
tes.t.
Is it best to use the bit-level thing and if so, any suggestions to it? Or is it better if I continue on the current and fix it up to work correctly (please provide solutions)?
Note, that performance isn't really needed here, this is just a one time thing (on startup) so, anything will do as long as it works.
The word has four letters, so there are three breaks where you could insert a dot '.'. There will be 2n-1 combinations of inserting/not inserting dots. You can encode them as binary numbers:
dec bin word
--- --- -------
0 000 test
1 001 t.est
2 010 te.st
3 011 t.e.st
4 100 tes.t
5 101 t.es.t
6 110 te.s.t
7 111 t.e.s.t
What you need to do now is to make a "mask" that changes from 0 to 2n-1-1, inclusive, and interpret this mask as a sequence of dots in a nested loop, like this:
string s = "test";
for (int mask = 0 ; mask != 1 << (s.size()-1) ; mask++) {
cout << s[0];
for (int i = 0 ; i != s.size()-1 ; i++) {
if (mask & (1<<i)) {
cout << ".";
}
cout << s[i+1];
}
cout << endl;
}
Demo.
Use an integer as a bitmask: for each bit, print a . if it is set. If you iterate all values from 0 to 2 ** (len-1) you will enumerate all possible positions for the dot with all possible combinations:
#include <stdio.h>
#include <string.h>
int main(void) {
char str[] = "test";
int len = strlen(str);
for (int bits = 0; bits < (1 << (len - 1)); bits++) {
putchar(str[0]);
for (int j = 1; j < len; j++) {
if (bits & (1 << (j - 1)))
putchar('.');
putchar(str[j]);
}
putchar('\n');
}
return 0;
}
This function should do what you expect:
void dotify(char *str) {
int nr = 1 << (strlen(str)-1);
char buf[strlen(str)*2];
while (nr--) {
int i;
char *ptr = buf;
for (i = 0; i < strlen(str); i++) {
*ptr++ = str[i];
if (nr & (1 << i))
*ptr++ = '.';
}
*ptr = '\0';
puts(buf);
}
}
The fundamental idea behind this solution is to map each dot-place to a digit of a binary number with strlen(str)-1 digits. Count this number from 0-n. Digit 0 means "don't set dot", while 1 means "set dot"
long time lurker, first time poster. I have been working on this problem for the last six hours hours.
Problem:
Implement the following functions. Each function deals with null terminated C-Style strings. You can assume that any char array passed into the functions will contain null terminated data. Place all of the functions in a single file and then create a main() function that tests the functions thoroughly.
Note: You may not use any c-string functions other than strlen().
I am having trouble with the fourth function.
The desired behavior is: This function returns the index in string s where the substring can first be found. For example if s is "Skyscraper" and substring is "ysc" the function would return 2. It should return -1 if the substring does not appear in the string.
prototype:
int findSubstring(char *str, char substring[])
Here's my two starts for function definitions, I'm not really sure if either is going in the right direction, I'm having a lot of trouble keeping the loop iterations in my head, any help would be TREMENDOUSLY appreciated.
int findSubstring(char *str, char substring[]){
int subS = -1, index1 = 0, index2 = 0;
int length1 = (strlen(str) - 1);
int length2 = (strlen(substring) - 1);
if(length1 > length2){
for(int i = 0; i <= length2; i++){
for(int j = 0; j <= length1; j++){
if(*(substring + i) == *(str + j) && *(substring +i) != '\0' ){
i++;
if(index1 == 0){
index1 = i;
}
}
if( *(substring + i) == '\0'){
subS = i + 2;
}
}
}
}
if (length1 < length2){
cout << "Invalid, substring exceeds size of string!" << endl;
}
return subS;
}
int findSubstring(char *str, char substring[]){
int index = -1;
int lengthStr = (strlen(str) - 1);
int lengthSub = (strlen(substring) - 1);
if (lengthStr < lengthSub){
cout << "Invalid input, substring exceeds size of string!" << endl;
}
if( lengthSub == 0){
cout << "";
}
if (lengthStr > lengthSub){
for(int i = 0; i <= lengthSub; i++){
for(int j = 0; j <= lengthStr; j++){
}
return index;
}
//You can replace my str.size() and subString.size() by the size of each c-string.
int stringPointerOperation( string str, string subString )
{
int pos=0;
bool notFound;
for(int i = 0; i < str.size() ; i++)
{
notFound= false;
if(str[i] == subString[0])
{
pos=i;
for(int k = 0 ; k < subString.size() && k < str.size() ; k++,i++)
{
if(subString[k] != str[i] )
{
notFound=true;
break;
}
}
}
}
if(notFound)
return -1;
else
return pos;
}
You are using the wrong strategy for finding a sub-string in a string. The outer for loop needs to iterate over the main string and the inner for loop needs to iterate over the sub-string.
Say you are looking for "de" in "abcdef". The strategy that I find easier to understand and implement is:
Can I find "de" starting from 0 of "abcdef". No, I can't.
Can I find "de" starting from 1 of "abcdef". No, I can't.
Can I find "de" starting from 2 of "abcdef". No, I can't.
Can I find "de" starting from 3 of "abcdef". Yes, I can. Return 3.
Here's a version that works for me.
int findSubstring(char *str, char substring[]){
int i;
int j;
int length1 = strlen(str);
int length2 = strlen(substring);
if(length1 < length2){
std::cout << "Invalid, substring exceeds size of string!" << std::endl;
return -1;
}
for(i = 0; i < length1; i++){
for(j = 0; j < length2; j++){
// The index to use access the element of str
// needs to be offset by i.
if( str[i+j] != substring[j] )
{
break;
}
}
if ( j == length2 )
{
return i;
}
}
return -1;
}
I'm trying to read characters (numbers) from a string, and then passing them as integers in a vector. Currently something like this:
int p;
std::string line = "1111222111"
std::vector<int> vec;
for(int i = 0; i < str.size(); i++)
{
if(line.find('0', static_cast<std::size_t>(i)) != line.npos)
p = 0;
else if(line.find('1', static_cast<std::size_t>(i)) != line.npos)
p = 1;
else if(line.find('2', static_cast<std::size_t>(i)) != line.npos)
p = 2;
vec.push_back(p);
}
When doing this, the vector ends only with 0's. Keep in mind that this is not the actual code, just a vague representation of the part where I have my problem. I think I must be doing something wrong in the line.find stuff, but I don't really know any other way to use it (not that I actually know how to really use it...). Thanks in advance guys!
You can make use of the isdigit function to determine if the character is a digit. If so, you can make use of the fact that ASCII orders the digits adjacent.
You can thus solve the problem with the following code:
for(int i = 0; i < str.size(); i++) {
int c = str[i]-'0';
if(c >= 0 && c <= 9) {
vec.push_back(c);
}
}
#include <vector>
#include <string>
int main(int argc, char *argv[])
{
std::vector<int> ans;
const std::string str = "1234";
for (int i = 0; i < str.size(); ++i) {
if ('0' <= str[i] && str[i] <= '9')
ans.push_back(str[i] - '0');
}
return 0;
}
I think you should instead of this :
for(int i = 0; i < str.size(); i++)
have this:
for(int i = 0; i < line.size(); i++)
str is not defined in your example. I think you meant line.
How would one go ahead and write parts of a string inside a for-loop? Let's say I have this code:
string str[64];
for( int i = 0; i < 64; i = i + 4 )
{
cin >> str[i];
}
Everytime it enters the loop, I want to write four elements of the string. How would I go ahead and to that, since the code I wrote does not work? :P
Thanks :)
Try this
for( int i = 0; i < 64; i = i + 4 )
{
for( int j = i; j < i + 4; j++ )
cin >> str[j];
}
Note that:
std::string str[64];
declares an array of 64 std::string objects. If you'd like to read from the standard input character by character and fill this array with strings of maximum length 4, then it could look like this:
char c;
for (int i = 0, j = 0; std::cin >> c && i < 64; ++j) {
str[i].push_back(c);
if (j == 3) {
i++;
j = 0;
}
}
However also consider to do the opposite thing:
read "long" string at once (if your input is within a single line, use std::getline)
use std::string::substr to tokenize this string into small strings of length 4
and if you need to hold these tokens in memory, use std::vector instead of an array
i.e. :
std::string line;
if (std::getline(std::cin, line))
{
size_t lineLen = line.length();
std::vector<std::string> tokens;
for (int i = 0; i < lineLen; i = i + 4)
tokens.push_back(line.substr(i,4));
for (size_t i = 0; i < tokens.size(); ++i)
std::cout << tokens[i] << ", ";
}
You might also consider calling tokens.reserve(len/4 + 1); after the tokens vector is constructed to prevent redundant memory reallocations. And don't forget to #include <vector>.