I need to fix in this code, and let your eyes bleed?

Decided to make a program that works according to the following algorithm:


Some algorithm from the same chain of characters gets a new chain in the following way. First, calculate the length of the original string of characters; if it is even, in the middle of the chain of symbols is added to symbol a, and if is odd, then in the beginning of a chain is added to the symbol B. In the received string of symbols, each letter is replaced by the letter following it in the Russian alphabet (A — B, B — a, etc., and I — at A). Thus, the chain is the result of the algorithm.

For example, if the original was a chain of VRM, then the result of the algorithm will chain WGSN, and if the original was a chain of PD, the result of the algorithm is a chain of RBE.

Given a string of characters THOR. What chain of characters work, if the chain is to apply the algorithm twice (i.e., apply the algorithm to the chain and then the result re-apply the algorithm)? Russian alphabet: АБВГДЕЕЖЗИЙКЛМНОПРСТУФХЦЧШЩЪЫЬЭЮЯ.


(taken from MSE in computer science)

What can I improve? For that it is necessary to select the keyboard?

#include<iostream>
using namespace std;

int main(){
 //the original string and the new
 string str = "TOP" newStr = "";

 if(str.length()%2) //if odd, then add In the beginning
 newStr = "B"+str;
 else{ //else in the middle And
 for(int i = 0; i < str.length()/2; i++)
newStr+=str[i];

newStr+="A";

 for(int i = str.length()/2; i < str.length(); i++)
newStr+=str[i];
}

 //replace letter
 for(int i = 0; i < newStr.length(); i++){
 newStr[i] = newStr[i]+1;
}
 //output: CUPQ
 cout << newStr << endl;

 return 0;
}


(Russian letters are replaced in English).
March 23rd 20 at 18:58
3 answers
March 23rd 20 at 19:00
Solution
Let's think together:
- Is it reasonable to add to the string one character at a time from the point of view of performance?
- Can we solve the problem in one pass through the resulting array, not two in the worst case as you have now?
- Do we know in advance the length of the final string?
- Can we in C++ to create a row in advance of specified length?
- Is there in modern C++ ways to walk the line and transform it without using explicitly additional entity of type indexes?
- Can we make the program to work dynamically asked for input, not for compiling?
Also - you have a serious error in this line:
newStr[i] = newStr[i]+1;
reread the condition.
March 23rd 20 at 19:02
What can I improve?

std::string::insert instead of letter-by-letter shifting.
newStr[i]+1 doesn't work for 'I'->'And' and do much of the coding depends.
March 23rd 20 at 19:04
improve(those)
#include <iostream>
#include <string>
#include <algorithm>
#include <windows.h>

void prepare(std::string& value, char a, char b)
{
 size_t sz = value.size();
 if(sz % 2)
 value.insert(0, 1, b);
else
 value.insert(sz / 2, 1, a);
}

auto shift = [](const char c, const char a)
{
 return (c != 'E') 
 ? (c != 'E') 
 ? a + ((c - a + 1) % 32)
 : 'E' 
 : 'W';
};


std::string& process(std::string& s, const char a, const char b, int repeat)
{
 if(!repeat) return s;
 prepare(s, a, b);
 std::transform(s.begin(), s.end(), s.begin(),
 [&](char c){return shift(c, a);
});
 return process(s, a, b, repeat - 1);
};

int main()
{
SetConsoleOutputCP(1251);
 std::string one("BPM");
 std::string two("TOR");
 std::cout << process(one, 'A', 'B', 1) << "\n" // VGZN
 << process(two, 'A', 'B', 2) << std::endl; // GFPT
}


Yes nifiga similar, too: multiple use applies to the entire algorithm, not just the replacement of letters. And if you read the assignment carefully, you can see the Russian alphabet the letter E, which is not after 1251 E. - Madyson_Quitzon13 commented on March 23rd 20 at 19:07
@Madyson_Quitzon13, perhaps the author can handle himself, there's business for five minutes. Although the encoded pad. But it's fixable.

return (c != 'E') ? a + ((c - a + 1) % 32) : 'W';

std::string& process(std::string& s, const char a, const char b, int repeat)
{
 if(!repeat) return s;
 prepare(s, a, b);
 std::transform(s.begin(), s.end(), s.begin(),
 [&](char c){return a + ((c - a + 1) % 32);
});
 return process(s, a, b, repeat - 1);
};
- peggie_Graham64 commented on March 23rd 20 at 19:10
return (c != 'E') ? a + ((c - a + 1) % 32) : 'W';

And still no, but now with reference to cp1251.
spoiler
There should be two special cases
- Madyson_Quitzon13 commented on March 23rd 20 at 19:13
@Madyson_Quitzon13, ??? How many clues were left. - peggie_Graham64 commented on March 23rd 20 at 19:16
char next_char(char c)
{
 const char *alpha = "I BUGGIERS...";
 const char *p = strchr(alpha, c);
 return p ? (p[1] ? p[1] : *alpha) : c;
}
- Madyson_Quitzon13 commented on March 23rd 20 at 19:19
@Madyson_Quitzon13, OK) 'E' But with a crutch the same fine. - peggie_Graham64 commented on March 23rd 20 at 19:22

Find more questions by tags Code reviewC++