Converting numbers into alphabets in c++ - c++

I'm trying to write a code that would convert numbers into alphabets. For example 1 will be 'A', 2 will be 'B', 3 will be 'C' and so on. Im thinking of writing 26 if statements. I'm wondering if there's a better way to do this...
Thank you!

Use an array of letters.
char nth_letter(int n)
{
assert(n >= 1 && n <= 26)
return "abcdefghijklmnopqrstuvwxyz"[n-1];
}

If you can rely on the using an ASCII character set where they are consecutive then you can convert
char intToAlphabet( int i )
{
return static_cast<char>('A' - 1 + i);
}
If you can sometimes rely on this fact, e.g. you can set a compiler flag or similar for the particular target, you can also use this code for that specific build.
Otherwise use a static lookup table (as others have suggested).
Note that it is preferable to "assert" your range check if your numbered input comes from program variables that you know should never be out of range.
If the input comes from user-provided data where the users could potentially provide rogue data, you need a way to handle it that is not "undefined behaviour". Therefore you would have to check each value and either throw an exception (informing the user to correct their data) or use some character to indicate a bad input.

something like that
my_print(int x)
{
char symbol = (char)('A' + x - 1);
cout << symbol;
}

The simplest way would be using a table:
char
remap( int original )
{
static char const remap[] = "ABCDEFGHIJKLMNOPQRSTUVWXYZ";
return original >= 0 && original < sizeof(remap) - 1
? remap[ original ]
: '?'; // or throw, or ...
}

If you want to convert 0 to a, 1 to b, 2 to c ... 25 to z:
char covertedChar = (char)('a' + 2);
// Will print 'c'
cout << covertedChar;
Similary, to convert 0 to A, 1 to B, 2 to C ... 25 to Z:
char covertedChar = (char)('A' + 25);
// Will print 'Z'
cout << covertedChar;
So if you want to convert 1 to A, 2 to B, 3 to C ... 26 to Z, simply subtract 1 offset.
int toCovert = 26 // 'Z'
char covertedChar = (char)('A' + toCovert - 1);
// Will print 'Z'
cout << covertedChar;

Related

my run-length encoding doesn't work with big numbers

I have a assingment were I need to code and decode txt files, for example: hello how are you? has to be coded as hel2o how are you? and aaaaaaaaaajkle as a10jkle.
while ( ! invoer.eof ( ) ) {
if (kar >= '0' && kar <= '9') {
counter = kar-48;
while (counter > 1){
uitvoer.put(vorigeKar);
counter--;
}
}else if (kar == '/'){
kar = invoer.get();
uitvoer.put(kar);
}else{
uitvoer.put(kar);
}
vorigeKar = kar;
kar = invoer.get ( );
}
but the problem I have is if need to decode a12bhr, the answer is aaaaaaaaaaaabhr but I can't seem to get the 12 as number without problems, I also can't use any strings or array's.
c++
I believe that you are making following mistake: imagine you give a32, then you read the character a and save it as vorigeKar (previous character, I am , Flemish so I understand Dutch :-) ).
Then you read 3, you understand that it is a number and you repeat vorigeKar three times, which leads to aaa. Then you read 2 and repeat vorigeKar two times, leading to aaaaa (five times, five equals 3 + 2).
You need to learn how to keep on reading numeric characters, and translate them into complete numbers (like 32, or 12 in your case).
Like #Dominique said in his answers, You're doing it wrong.
Let me tell you my logic, you can try it.
Pesudo Code + Logic:
Store word as a char array or string, so that it'll be easy to print at last
Loop{
Read - a //check if it's number by subtracting from '0'
Read - 1 //check if number = true. Store it in int res[] = res*10 + 1
//Also store the previous index in an index array(ie) index of char 'a' if you encounter a number first time.
Read - 2 //check if number = true. Store it in res = res*10 + 2
Read - b , h and so on till "space" character
If you encounter another number, then store it's previous character's index in index array and then store the number in a res[] array.
Now using index array you can get the index of your repeating character to be printed and print it for it's corresponding times which we have stored in the result array.
This goes for the second, third...etc:- numbers in your word till the end of the word
}
First, even though you say you can't use strings, you still need to know the basic principle behind how to turn a stream of digit characters into an integer.
Assuming the number is positive, here is a simple function that turns a series of digits into a number:
#include <iostream>
#include <cctype>
int runningTotal(char ch, int lastNum)
{
return lastNum * 10 + (ch -'0');
}
int main()
{
// As a test
char s[] = "a123b23cd1/";
int totalNumber = 0;
for (size_t i = 0; s[i] != '/'; ++i)
{
char digit = s[i]; // This is the character "read from the file"
if ( isdigit( digit) )
totalNumber = runningTotal(digit, totalNumber);
else
{
if ( totalNumber > 0 )
std::cout << totalNumber << "\n";
totalNumber = 0;
}
}
std::cout << totalNumber;
}
Output:
123
23
1
So what was done? The character array is the "file". I then loop for each character, building up the number. The runningTotal is a function that builds the integer from each digit character encountered. When a non-digit is found, we output that number and start the total from 0 again.
The code does not save the letter to "multiply" -- I leave that to you as homework. But the code above illustrates how to take digits and create the number from them. For using a file, you would simply replace the for loop with the reading of each character from the file.

Using getchar_unlocked()

I recently learnt that using getchar_unlocked() is a faster way of reading input.
I searched on the internet and found the code snippet below:
But I am unable to understand it.
void fast_scanf(int &number)
{
register int ch = getchar_unlocked();
number= 0;
while (ch > 47 && ch < 58) {
number = number * 10 + ch - 48;
ch = getchar_unlocked();
}
}
int main(void)
{
int test_cases;fast_scanf(test_cases);
while (test_cases--)
{
int n;
fast_scanf(n);
int array[n];
for (int i = 0; i < n; i++)
fast_scanf(array[i]);
}
return 0;
}
So, this code takes input for an integer array of size n for a given number of test_cases . I didn't understand anything in the function fast_scanf, like why this line:
while (ch > 47 && ch < 58)
{ number = number * 10 + ch - 48;
why the register is used while declaring ch?
why the getchar_unlocked() is used twice in the function? and so on..
It would be great help if someone elaborates this for me. Thanks in advance!
Okay, since what you are asking needs to be explained clearly, I am writing it here... so I don't jumble it all up inside the comments...
The function: (Edited it a bit to make it look like more C++-standard)
void fast_scanf(int &number)
{
auto ch = getchar_unlocked();
number= 0;
while (ch >= '0' && ch <= '9')
{
number = number * 10 + ch - '0';
ch = getchar_unlocked();
}
}
Here, take up consideration by looking at the ASCII Table first, since you won't understand how the results are coming up if you don't...
1) Here, you have a character ch takes up the input character from the user using getchar_unlocked() (The auto keyword does that automatically for you and is only usable in C++, not C)...
2) You assign the variable number to zero so that the variable can be re-used, note that the variable is a reference so it changes inside your program as well...
3) while (ch >= '0' && ch <= '9')... As pointed out, checks whether the characters is within the numerical ASCII limit, similar to saying that the character has to be greater than or equal to 48 but less than or equal to 57...
4) Here, things are a little bit tricky, Variable number is multiplied with the product of itself and 10 and the real integer value of the character you stored)...
5) In the next line, ch is reassigned so that you don't have to stay in the loop forever, since ch will remain that number forever if the user doesn't type anything... remember a loop goes back to where it was declared after reaching the end, checks if the condition is true, continues if it is true else breaks)...
For example: 456764
Here, ch will first take 4 then the others follow so we go with 4 first...
1) Number will be assigned to zero. While loop checks if the given character is a number or not, if it is continues the loop else breaks it...
2) Multiplication of 0 with 10 will be zero... and adding it with difference 52 (that is '4') with 48 (that is '0') gives you 4 (the real numerical value, not the char '4')...
So the variable number now is 4...
And the same continues with the others as well... See...
number = number * 10 + '5' - '0'
number = 4 * 10 + 53 - 48
number = 40 + 5
number = 45... etc, etc. for other numbers...

Error in converting integer to spreadsheet column_id (1 to 'A', 2 to 'B'...)

I want to convert an integer entered into spreadsheet column_id ,that is
1 to A, 2 to B, 26 to Z, 27 to AA and so on.
My code is running correctly for all inputs except for the multiples of 26 and I am unable to form the logic for it. What could be the possible logic for it?
#include<iostream>
#include<algorithm>
using namespace std;
int main(){
int a,n;
string b;
cin>>a;
b="";
while(a){
b+=((a%26)+'A'-1);
a/=26;
}
reverse(b.begin(),b.end());
cout<<b<<"\n";
return 0;
}
Input-
26
Output-
A#
Expected Output-
Z
So first of all: Why is this error occurring?
If you chose to enter 26 as an value for a you are calculating the value for b as follows:
b += ((26 % 26) + 'A' - 1); // or
b += (0 + 'A' - 1); // or
b += 'A' - 1; // which is equal to the '#' symbol
So obviously you do not wan't to subtract from the letter it self. But what happens if you decrease a before using the modulo operator?
a--;
while (a) {
b+=static_cast<char>('A' + (a % 26));
a/=26;
}
Well this will now work correctly for values from 1-26 but will not work for values above 26 an won't enter the loop in case you enter 1 for a. Switching to a do-while loop will fix the latter but there will still be an issue. For every number greater than 26 you will get an string wich is 27 cells ahead (so BA instead of AA). But by moving a-- into the loop this will be fixed as well:
do {
a--;
b+=static_cast<char>('A' + (a % 26)); // static_cast not needed just for clarity
a/=26;
} while(a);
Here is a working example.

What approach should I take towards converting ascii chars to other chars in c++

Well currently I am re creating my own version of enigma as a little project but if you understand how the enigma machine works it has rotors which connect a character to a completely different character for example A might be connected to F or U may be connected to C and this is done three times. Currently I am getting the char for the rotor by using this function:
char getRotorOne(char i) {
if(i == 'a') {
return 'g';
}if(i == 'b') {
return 'A';
}if(i == 'c') {
return 'o';
}
The main problem with this is it takes a long time to write and it seems inefficient and I think there must be a better way. The other problem with this is on the original enigma machine there were only the 26 letters of the alphabet on this there are the 94 tapeable characters of ascii (32-126) is there any other simpler way that this can be done? If you think this question is unclear or you don't understand please tell me instead of just flagging my post, then you can help me improve my question.
Use tables! Conveniently, C string literals are arrays of characters. So you can do this:
// abc
const char* lower_mapping = "gAo";
// ABC
const char* upper_mapping = "xyz";
char getRotorOne(char i) {
if (i >= 'a' && i <= 'z') return lower_mapping[i - 'a'];
if (i >= 'A' && i <= 'Z') return upper_mapping[i - 'A'];
assert(false && "Unknown character cannot be mapped!");
}
Since chars are really just small integers, and ASCII guarantees contiguous ranges for a-z and A-Z (and 0-9) you can subtract from a given character the first one in its range (so, 'a' or 'A') to get an index into that range. That index can then be used to look up the corresponding character via a table, which in this case is just a simple hardcoded string literal.
This is an improvement on Cameron's answer. You should use a simple char array for each rotor, but as you said you want to process ASCII characters in the range 32-126, you should build each mapping as an array of 95 characters:
char rotor1[95] ="aXc;-0..."; // the 95 non control ascii characters in arbitrary order
Then you write your rotor function that way:
char getRotorOne(char i) {
if ((i < 32) || (i > 126)) return i; // do not change non processed characters
return rotor1[i - 32]; // i - 32 is in range 0 - 94: rotor1[i - 32] is defined
}

Separating every second digit in an integer C++

I am currently finishing up an assignment I have to complete for my OOP class and I am struggling with 1 part in particular. Keep in mind I am still a beginner. The question is as followed:
If the string contains 13 characters, all of characters are digits and the check digit is modulo 10, this function returns true; false otherwise.
This is in regards to a EAN. I basically have to separate every second digit from the rest digits. for example 9780003194876 I need to do calculations with 7,0,0,1,4,7. I have no clue about doing this.
Any help would be greatly appreciated!
bool isValid(const char* str){
if (atoi(str) == 13){
}
return false;
}
You can start with a for loop which increments itself by 2 for each execution:
for (int i = 1, len = strlen(str); i < len; i += 2)
{
int digit = str[i] - '0';
// do something with digit
}
The above is just an example though...
Since the question was tagged as C++ (Not C, so I suggest other answerers to not solve this using C libraries, please. Let us getting OP's C++ knoweledge in the right way since the beggining), and is an OOP class I'm going to solve this with the C++ way: Use the std::string class:
bool is_valid( const std::string& str )
{
if( str.size() == 13 )
{
for( std::size_t i = 0 ; i < 13 ; i += 2 )
{
int digit = str[i] - '0';
//Do what you wan't with the digit
}
}
else
return false;
}
First, if it's EAN, you have to process every digit, not just
every other one. In fact, all you need to do is a weighted sum
of the digits; for EAN-13, the weigths alternate between 1 and
3, starting with three. The simplest solution is probably to
put them in a table (i.e. int weigt[] = { 1, 3, 1, 3... };,
and iterate over the string (in this case, using an index rather
than iterators, since you want to be able to index into
weight as well), converting each digit into a numerical value
(str[i] - '0', if isdigit(static_cast<unsigned char>(str[i])
is true; if it's false, you haven't got a digi.), then
multiplying it by the running total. When you're finished, if
the total, modulo 10, is 0, it's correct. Otherwise, it isn't.
You certainly don't want to use atoi, since you don't want the
numerical value of the string; you want to treat each digit
separately.
Just for the record, professionally, I'd write something like:
bool
isValidEAN13( std::string const& value )
{
return value.size() == 13
&& std::find_if(
value.begin(),
value.end(),
[]( unsigned char ch ){ return !isdigit( ch ); } )
== value.end()
&& calculateEAN13( value ) == value.back() - '0';
}
where calculateEAN13 does the actual calculations (and can be
used for both generation and checking). I suspect that this
goes beyond the goal of the assignment, however, and that all
your teacher is looking for is the calculateEAN13 function,
with the last check (which is why I'm not giving it in full).