c++ How to convert string array to char array - c++

my program should have store = 5 string values - Simpsun GN120, Sonic Lux10, Ultimax G42, Antalpha A200 and Nickov N230 and then make a calculation that will make code for each value. Code would take first 3 letters and 3 last letters of a value.
first code from value: Simpsun GN120
would look like this: Sim120
my biggest issue was that i couldn't make a string array as getting a length of each value in array would crash a program so for now i have made program that will do this calculation but only if string is not array if someone could give me some tips how i could improve my code to make that string in to array
#include <iostream>
using namespace std;
int main()
{
string str = "Simpsun GN120";
int i;
string productCode[5];
for (i = 0; i < str.length(); i++)
{
if (i == 0 || i == 1 || i == 2)
{
productCode[0] += str[i];
}
if (i == str.length() - 1 || i == str.length() - 2 || i == str.length() - 3)
{
productCode[0] += str[i];
}
}
cout << productCode[0];
}

It's simple using string class .Run a loop to execute
productCode[i] = str[i].substr(0, 3) + str[i].substr(str[i].length() - 3);
and your work is done.

jignatius Thank you very much for that answer!
using namespace std;
int main()
{
string str[2] = { "Simpsun GN120", "Sonic Lux10" };
int i;
string productCode[5];
for (int i = 0; i < 2; i++)
{
productCode[i] = str[i].substr(0, 3) + str[i].substr(str[i].length() - 3);
}
cout << productCode[0] << endl;
cout << productCode[1];
}

Related

namenum usaco problem keeps getting bad_alloc errors [duplicate]

This question already has answers here:
Testing stream.good() or !stream.eof() reads last line twice [duplicate]
(3 answers)
Why is iostream::eof inside a loop condition (i.e. `while (!stream.eof())`) considered wrong?
(5 answers)
Closed 24 days ago.
I'm currently working on the "Name That Number" USACO training problem.
It takes a number as input and outputs any matching names found in a dictionary using touch tone telephone keymapping.
The full code consistently gets a bad_alloc thrown on the USACO grader. I've been coding in a replit and it runs fine each time. I've also tried commenting out different parts of the code and running it on the USACO grader but sometimes it runs fine and sometimes it gets a bad_alloc thrown. I think it has something to do with my 2d array of vectors but I'm not sure exactly what or how to fix it.
/*
ID:*****
TASK: namenum
LANG: C++14
*/
#include <iostream>
#include <fstream>
#include <string>
#include <vector>
using namespace std;
//function that takes letter and returns associated number
int convert(int letter){ //implicit conversion
if (letter < 81){
letter = letter - 65;
}
else {
letter = letter - 66;
}
int modify = letter % 3;
letter = (letter - modify) / 3 + 2;
return letter;
}
int main() {
ifstream numin ("namenum.in");
ifstream dictin ("dict.txt");
ofstream fout ("namenum.out");
//2d array storing vectors that will store matching names for that index
vector<string> names[8][8]{};
//read names in from dict and store in table
while (dictin.good())
{
string name{};
dictin >> name;
if (name[0] != 'Z' && name[1] != 'Z'){
int i = convert(name[0]) - 2;
int j = convert(name[1]) - 2;
names[i][j].push_back(name);
}
}
//read in digits from input
string digits{};
numin >> digits;
//output matches
int index1 = static_cast<int>(digits[0]) - 50;
int index2 = static_cast<int>(digits[1]) - 50;
string output{};
//check for matches
if (index1 >= 0 && index1 <= 8 && index1 >= 0 && index1 <= 8){
for (int i = 0; i < names[index1][index2].size(); i++){
string matchdigits{};
for (int j = 0; j < names[index1][index2][i].length(); j++){
matchdigits += static_cast<char>(convert(names[index1][index2][i][j]) + 48);
}
if (matchdigits == digits){
output = names[index1][index2][i] + "\n";
}
}
}
if (output == ""){
output = "NONE\n";
}
fout << output;
return 0;
}

I am currently trying to save a set of integers in a int array, by redefining string into numbers, then store it in the array

I am trying to convert input text/numbers (string), which will include any characters, but I want to separate the numbers from the characters and store them into an integer array, once it is converted from a string.
I believe the problem is where the string is converting to an integer by use of stoi(), but I cannot seem to spot the problem.
Currently, the code accepts any input and turns it into a string, the string is then checked character by character, and all the numbers without separation with comma or space is added together, once a comma or space, or any other character separates the number, the number as a whole is added to the array, and then continues to check the string for more numbers.
Any ideas?
Input Example1: 12, 13, 15
Input Example2: 12 13 15
Input Example3: 12ab13cd15ef
Result in integer array: 0[12] 1[13] 2[15]
These numbers will be used in the specific order, by using the numbers within the array.
#include<iostream>
#include<string>
#include <sstream>
using namespace std;
int main()
{
string datainput, str1, str3;
cin >> datainput;
int n = 0, raycount = 0, c;
int myray[10];
while (datainput[n])
{
if (datainput[n] == ('0') || datainput[n] == ('1') || datainput[n] == ('2') || datainput[n] == ('3') || datainput[n] == ('4') ||
datainput[n] == ('5') || datainput[n] == ('6') || datainput[n] == ('7') || datainput[n] == ('8') || datainput[n] == ('9'))
{
str1 = datainput[n];
str3 += str1;
}
else
{
c= stoi(str3);
c >> myray[raycount];
raycount++;
}
n++;
}
cout << myray[0] << endl;
cout << myray[1] << endl;
cout << myray[2] << endl;
cout << myray[3] << endl;
system("pause");
return 0;
}
I see quite a few issues with your code.
Prior to C++11, while (datainput[n]) has undefined behavior once n reaches the end of the string.
The way you are checking for numeric digits can be greatly simplified using std::isdigit(), or even just a simple range check using the >= and <= operators.
You are not correctly accounting for numbers that are separated by other characters, or when the last number in the string is at the very end of the string.
The statement c >> myray[raycount]; needs to be changed to myray[raycount] = c; instead. And you are not breaking your loop if raycount reaches the max capacity of myray[].
You are not resetting str3 back to an blank string after converting it with std::stoi(). You just keep appending new digits to the end of previous digits with no break in between numbers.
With that said, try something more like this instead:
#include <iostream>
#include <string>
using namespace std;
int main()
{
string datainput, str3;
cin >> datainput;
int myray[10];
int raycount = 0;
bool gettingDigits = false;
for (int n = 0; n < datainput.size(); ++n)
{
char ch = datainput[n];
//if (isdigit(ch))
if (ch >= '0' && ch <= '9')
{
if (!gettingDigits)
{
str3 = "";
gettingDigits = true;
}
str3 += ch;
}
else
{
if (gettingDigits)
{
myray[raycount] = stoi(str3);
raycount++;
str3 = "";
gettingDigits = false;
if (raycount == 10) break;
}
}
}
if (gettingDigits && (raycount < 10))
{
myray[raycount] = stoi(str3);
raycount++;
}
for (int n = 0; n < raycount; ++n)
cout << myray[n] << endl;
system("pause");
return 0;
}
Live Demo
Alternatively:
#include <iostream>
#include <string>
using namespace std;
int main()
{
string datainput, str3;
cin >> datainput;
int myray[10];
int raycount = 0;
string::size_type start = datainput.find_first_of("0123456789");
string::size_type end;
while (start != string::npos)
{
end = datainput.find_first_not_of("0123456789", start+1);
if (end == string::npos)
{
str3 = datainput.substr(start);
myray[raycount] = stoi(str3);
raycount++;
break;
}
str3 = datainput.substr(start, end-start);
myray[raycount] = stoi(str3);
raycount++;
if (raycount == 10) break;
start = datainput.find_first_of("0123456789", end+1);
}
for (int n = 0; n < raycount; ++n)
cout << myray[n] << endl;
system("pause");
return 0;
}
Live Demo
So, you want to segregate numbers and characters into different arrays.
In if block, you are checking for characters, so, I suspect stoi() wouldn't work.
Better typecast it to an integer.
int temp[10];
if (datainput[n] == ('0') || ...) {
temp[n] = int(datainput[n]);
}
This way your temp array would contain the numbers.

What's wrong with my dynamic programming algorithm with memoization?

*Sorry about my poor English. If there is anything that you don't understand, please tell me so that I can give you more information that 'make sence'.
**This is first time asking question in Stackoverflow. I've searched some rules for asking questions correctly here, but there should be something I missed. I welcome all feedback.
I'm currently solving algorithm problems to improve my skill, and I'm struggling with one question for three days. This question is from https://algospot.com/judge/problem/read/RESTORE , but since this page is in KOREAN, I tried to translate it in English.
Question
If there are 'k' pieces of partial strings given, calculate shortest string that includes all partial strings.
All strings consist only lowercase alphabets.
If there are more than 1 result strings that satisfy all conditions with same length, choose any string.
Input
In the first line of input, number of test case 'C'(C<=50) is given.
For each test case, number of partial string 'k'(1<=k<=15) is given in the first line, and in next k lines partial strings are given.
Length of partial string is between 1 to 40.
Output
For each testcase, print shortest string that includes all partial strings.
Sample Input
3
3
geo
oji
jing
2
world
hello
3
abrac
cadabra
dabr
Sample Output
geojing
helloworld
cadabrac
And here is my code. My code seems to work perfect with Sample Inputs, and when I made test inputs for my own and tested, everything worked fine. But when I submit this code, they say my code is 'wrong'.
Please tell me what is wrong with my code. You don't need to tell me whole fixed code, I just need sample inputs that causes error with my code. Added code description to make my code easier to understand.
Code Description
Saved all input partial strings in vector 'stringParts'.
Saved current shortest string result in global variable 'answer'.
Used 'cache' array for memoization - to skip repeated function call.
Algorithm I designed to solve this problem is divided into two function -
restore() & eraseOverlapped().
restore() function calculates shortest string that includes all partial strings in 'stringParts'.
Result of resotre() is saved in 'answer'.
For restore(), there are three parameters - 'curString', 'selected' and 'last'.
'curString' stands for currently selected and overlapped string result.
'selected' stands for currently selected elements of 'stringParts'. Used bitmask to make my algorithm concise.
'last' stands for last selected element of 'stringParts' for making 'curString'.
eraseOverlapped() function does preprocessing - it deletes elements of 'stringParts' that can be completly included to other elements before executing restore().
#include <algorithm>
#include <iostream>
#include <vector>
#include <cstring>
#include <string>
#define MAX 15
using namespace std;
int k;
string answer; // save shortest result string
vector<string> stringParts;
bool cache[MAX + 1][(1 << MAX) + 1]; //[last selected string][set of selected strings in Bitmask]
void restore(string curString, int selected=0, int last=0) {
//base case 1
if (selected == (1 << k) - 1) {
if (answer.empty() || curString.length() < answer.length())
answer = curString;
return;
}
//base case 2 - memoization
bool& ret = cache[last][selected];
if (ret != false) return;
for (int next = 0; next < k; next++) {
string checkStr = stringParts[next];
if (selected & (1 << next)) continue;
if (curString.empty())
restore(checkStr, selected + (1 << next), next + 1);
else {
int check = false;
//count max overlapping area of two strings and overlap two strings.
for (int i = (checkStr.length() > curString.length() ? curString.length() : checkStr.length())
; i > 0; i--) {
if (curString.substr(curString.size()-i, i) == checkStr.substr(0, i)) {
restore(curString + checkStr.substr(i, checkStr.length()-i), selected + (1 << next), next + 1);
check = true;
break;
}
}
if (!check) { // if there aren't any overlapping area
restore(curString + checkStr, selected + (1 << next), next + 1);
}
}
}
ret = true;
}
//check if there are strings that can be completely included by other strings, and delete that string.
void eraseOverlapped() {
//arranging string vector in ascending order of string length
int vectorLen = stringParts.size();
for (int i = 0; i < vectorLen - 1; i++) {
for (int j = i + 1; j < vectorLen; j++) {
if (stringParts[i].length() < stringParts[j].length()) {
string temp = stringParts[i];
stringParts[i] = stringParts[j];
stringParts[j] = temp;
}
}
}
//deleting included strings
vector<string>::iterator iter;
for (int i = 0; i < vectorLen-1; i++) {
for (int j = i + 1; j < vectorLen; j++) {
if (stringParts[i].find(stringParts[j]) != string::npos) {
iter = stringParts.begin() + j;
stringParts.erase(iter);
j--;
vectorLen--;
}
}
}
}
int main(void) {
int C;
cin >> C; // testcase
for (int testCase = 0; testCase < C; testCase++) {
cin >> k; // number of partial strings
memset(cache, false, sizeof(cache)); // initializing cache to false
string inputStr;
for (int i = 0; i < k; i++) {
cin >> inputStr;
stringParts.push_back(inputStr);
}
eraseOverlapped();
k = stringParts.size();
restore("");
cout << answer << endl;
answer.clear();
stringParts.clear();
}
}
After determining which string-parts can be removed from the list since they are contained in other string-parts, one way to model this problem might be as the "taxicab ripoff problem" problem (or Max TSP), where each potential length reduction by overlap is given a positive weight. Considering that the input size in the question is very small, it seems likely that they expect a near brute-force solution, with possibly some heuristic and backtracking or other form of memoization.
Thanks Everyone who tried to help me solve this problem. I actually solved this problem with few changes on my previous algorithm. These are main changes.
In my previous algorithm I saved result of restore() in global variable 'answer' since restore() didn't return anything, but in new algorithm since restore() returns mid-process answer string I no longer need to use 'answer'.
Used string type cache instead of bool type cache. I found out using bool cache for memoization in this algorithm was useless.
Deleted 'curString' parameter from restore(). Since what we only need during recursive call is one previously selected partial string, 'last' can replace role of 'curString'.
CODE
#include <algorithm>
#include <iostream>
#include <vector>
#include <cstring>
#include <string>
#define MAX 15
using namespace std;
int k;
vector<string> stringParts;
string cache[MAX + 1][(1 << MAX) + 1];
string restore(int selected = 0, int last = -1) {
if (selected == (1 << k) - 1) {
return stringParts[last];
}
if (last == -1) {
string ret = "";
for (int next = 0; next < k; next++) {
string resultStr = restore(selected + (1 << next), next);
if (ret.empty() || ret.length() > resultStr.length())
ret = resultStr;
}
return ret;
}
string& ret = cache[last][selected];
if (!ret.empty()) {
cout << "cache used in [" << last << "][" << selected << "]" << endl;
return ret;
}
string curString = stringParts[last];
for (int next = 0; next < k; next++) {
if (selected & (1 << next)) continue;
string checkStr = restore(selected + (1 << next), next);
int check = false;
string resultStr;
for (int i = (checkStr.length() > curString.length() ? curString.length() : checkStr.length())
; i > 0; i--) {
if (curString.substr(curString.size() - i, i) == checkStr.substr(0, i)) {
resultStr = curString + checkStr.substr(i, checkStr.length() - i);
check = true;
break;
}
}
if (!check)
resultStr = curString + checkStr;
if (ret.empty() || ret.length() > resultStr.length())
ret = resultStr;
}
return ret;
}
void EraseOverlapped() {
int vectorLen = stringParts.size();
for (int i = 0; i < vectorLen - 1; i++) {
for (int j = i + 1; j < vectorLen; j++) {
if (stringParts[i].length() < stringParts[j].length()) {
string temp = stringParts[i];
stringParts[i] = stringParts[j];
stringParts[j] = temp;
}
}
}
vector<string>::iterator iter;
for (int i = 0; i < vectorLen - 1; i++) {
for (int j = i + 1; j < vectorLen; j++) {
if (stringParts[i].find(stringParts[j]) != string::npos) {
iter = stringParts.begin() + j;
stringParts.erase(iter);
j--;
vectorLen--;
}
}
}
}
int main(void) {
int C;
cin >> C;
for (int testCase = 0; testCase < C; testCase++) {
cin >> k;
for (int i = 0; i < MAX + 1; i++) {
for (int j = 0; j < (1 << MAX) + 1; j++)
cache[i][j] = "";
}
string inputStr;
for (int i = 0; i < k; i++) {
cin >> inputStr;
stringParts.push_back(inputStr);
}
EraseOverlapped();
k = stringParts.size();
string resultStr = restore();
cout << resultStr << endl;
stringParts.clear();
}
}
This algorithm is much slower than the 'ideal' algorithm that the book I'm studying suggests, but it was fast enough to pass this question's time limit.

my code doesn't run some thing wrong about strings, c++

I was training on solving algorithms, I wrote a code but it won't compile
in (if) I can not check s[i]=='S' .
I'm trying to if s[i] is S character or not but I don't know where my problem is.
If I can't use this syntax, what could be a solution?
#include<iostream>
#include<string>
using namespace std;
int main()
{
double v_w=25,v_s=25,d_w=25,d_s=25;
int n;
cin>>n;
string s[]={"WSSS"};
int i ;
for (i=0; i<n; i++)
{
if( s[i] == "W" )
{
v_s += 50;
d_w = d_w + (v_w/2);
d_s = d_s + (v_s/2);
cout<<"1 \n";
}
if(s[i]=='W')
{
v_w +=50;
d_w = d_w + (v_w/2);
d_s = d_s + (v_s/2);
cout<<"2 \n";
}
return 0;
}
cout<< d_w<<endl<<d_s;
}
string s[]={"WSSS"}; means an array of strings which the first one is "WSSS".
What you need is:
std::string s="WSSS";
string s[] = {"Hello"} is an array of strings (well, of one string).
If you iterate over it, or index into it s[0] is "Hello".
Whereas
string s{"Hello"} is one string, which is made up of characters.
If you iterate over it, or index into it s[0], you will get 'H'.
To pre-empt all the other things that are going to go wrong when the string versus character problem is sorted, lets move the return 0; from the middle of the for loop.
Then let's think about what happens if the number n entered is larger than the length of the string:
int n;
cin>>n; //<- no reason to assume this will be s.length (0 or less) or even positive
string s{"WSSS"}; //one string is probably enough
int i ;
for(i=0;i<n;i++)
{
if( s[i] == 'W' ) //ARGGGGGGG may have gone beyond the end of s
{
In fact, let's just drop that for now and come back to it later. And let's use a range based for loop...
#include<iostream>
#include<string>
using namespace std;
int main()
{
double v_w = 25, v_s = 25, d_w = 25, d_s = 25;
string s{ "WSSS" };
for (auto && c : s)
{
if (c == 'W')
{
v_w += 50;
d_w = d_w + (v_w / 2);
d_s = d_s + (v_s / 2);
cout << "2 \n";
}
}
cout << d_w << '\n' << d_s << '\n'; //<- removed endl just because...
return 0;
}
s is an array of strings in this case it has only element:
string s[] = {"WSSS"};
so writing s[2]; // is Undefined behavior
your code will produce a UB if the user enters n greater than the number of elements in s:
n = 4;
for(i = 0; i < n; i++) // s[3] will be used which causes UB
{
if( s[i] == 'W' ) // s[i] is a string not just a single char
{
}
}
also as long as s is an array of strings then to check its elements check them as strings not just single chars:
if( s[i] == "W" ) // not if( s[i] == 'W' )
I think you wanted a single string:
string s = {"WSSS"};
because maybe you are accustomed to add the subscript operator to character strings:
char s[] = {"WSSS"};
if so then the condition above is correct:
if( s[i] == 'W' )

How to convert a string of integer numbers into an array in c++?

The problem:
A function which gets degrees and factors as inputs and returns a equation as output.
The issue:
I did not know how to read an array of numbers in form of a string in c++ back then in 2016 when I was a super junior. I also did not know how to search good enough!
Update:
I answered my question and you can test this in this link: http://cpp.sh/42dwz
Answer details:
Main part of the code will be like this:
int main()
{
Poly mypoly("2 -4 3", "1 5 1");
return 0;
}
Inputs are 2 -4 3 and 1 5 1.
Output should be (2X) + (-4X5) + (3X)
Class Poly has a built-in feature to print the result
To make it easier we should convert degrees and factors from a single string into an array of strings.
This means that a string like 2 -4 3 changes into [2, -4, 3] which makes it easy to iterate over items and create equation sentences
This action is called splitting a string into an array by a delimiter which I found here for c++ https://stackoverflow.com/a/16030594/5864034
Rest of the code is just looping over the array of degrees and factors to create sentences(which is pretty easy just check the answer link http://cpp.sh/42dwz)
The code:
// Example program
#include <iostream>
#include <string>
#include <sstream>
#include <iterator>
using namespace std;
template <size_t N>
void splitString(string (&arr)[N], string str)
{
int n = 0;
istringstream iss(str);
for (auto it = istream_iterator<string>(iss); it != istream_iterator<string>() && n < N; ++it, ++n)
arr[n] = *it;
}
class Poly {
public:
string degree[10];
string factor[10];
Poly(string input_degree, string input_factor) {
splitString(degree, input_degree);
splitString(factor, input_factor);
for (int i = 0; i < 10; i++){
int this_degree = stoi(degree[i]);
int this_factor = stoi(factor[i]);
string this_sentence = "";
if(this_degree != 1 && this_degree != 0 ){
this_sentence = this_sentence + degree[i];
if(this_factor != 0){
if(this_factor != 1){
this_sentence = this_sentence + "X" + factor[i];
}else{
this_sentence = this_sentence + "X";
}
}
}
if(this_sentence != ""){
cout << "(" << this_sentence << ")";
}
if(stoi(degree[i+1]) != 0 && stoi(degree[i+1]) != 1){
cout << " + ";
}
}
}
};
int main()
{
Poly mypoly("2 -4 3", "1 5 1");
return 0;
}
The process of reading a string and extracting information from it into some sort of structure is called parsing. There are many ways to do this, and which way is appropriate depends on exactly what you want to do, how quickly it needs to run, how much memory you've got available and various other things.
You can write a simple loop which steps over each character and decides what to do based on some variables that store current state - so you might have a flag that says you're in the middle of a number, you see another digit so you add that digit to another variable which is collecting the digits of the current number. When the current number completes (perhaps you find a character which is a space), you can take what's in the accumulator variable and parse that into a number using the standard library.
Or you can make use of standard library features more fully. For your example, you'll find that std::istringstream can do what you want, out of the box, just by telling it to extract ints from it repeatedly until the end of the stream. I'd suggest searching for a good C++ input stream tutorial - anything that applies to reading from standard input using std::cin will be relevant, as like std::istringstream, cin is an input stream and so has the same interface.
Or you could use a full-blown parsing library such as boost::spirit - total overkill for your scenario, but if you ever need to do something like parsing a structured configuration file or an entire programming language, that kind of tool is very useful.
So for the community rules and to make it clear i want to answer my question.
#include <iostream>
#include <string>
#include <sstream>
#include <iterator>
using namespace std;
template <size_t N>
void splitString(string (&arr)[N], string str)
{
int n = 0;
istringstream iss(str);
for (auto it = istream_iterator<string>(iss); it != istream_iterator<string>() && n < N; ++it, ++n)
arr[n] = *it;
}
class Poly {
public:
string degree[10];
string factor[10];
Poly(string input_degree, string input_factor) {
splitString(degree, input_degree);
splitString(factor, input_factor);
for (int i = 0; i < 10; i++){
int this_degree = stoi(degree[i]);
int this_factor = stoi(factor[i]);
string this_sentence = "";
if(this_degree != 1 && this_degree != 0 ){
this_sentence = this_sentence + degree[i];
if(this_factor != 0){
if(this_factor != 1){
this_sentence = this_sentence + "X" + factor[i];
}else{
this_sentence = this_sentence + "X";
}
}
}
if(this_sentence != ""){
cout << "(" << this_sentence << ")";
}
if(stoi(degree[i+1]) != 0 && stoi(degree[i+1]) != 1){
cout << " + ";
}
}
}
};
int main()
{
Poly mypoly("2 1 -4", "1 3 5");
return 0;
}