Can someone explain the " - '0' " [duplicate] - c++

This question already has answers here:
understanding c-'0'
(7 answers)
Closed 9 years ago.
#include <iostream> // cin, cout
using namespace std;
int main(void)
{
char c[80];
int i, sum=0;
cin.getline(c,80);
for(i=0; c[i]; i++) // c[i] != '\0'
if('0'<=c[i] && c[i]<='9') sum += c[i]-'0';
cout<< "Sum of digits = " << sum << endl;
getchar();
getchar();
return 0;
}
I understand everything accept for the sum += c[i] - '0'; i removed the "-'0'" and it didn't give me the correct answer. Why is this?

This converts a character from its character code(which is 48 in ASCII for instance) to its integer equivalent. Thus it turns the character '0' to the value 0 as integer. As Pete Becker noted in a comment in the language definitions of both C and C++ it is required that all number characters are consecutive.

'0' returns the ASCII value of 0. Therefore to use the numbers and not their ASCII values, you need to offset by the ASCII value of 0.
'1' - '0' ::= 49 - 48 ::= 1 (49 and 48 are respectively ASCII values for 1 and 0).

It converts a character to the integer value:
character | ASCII code | expression | equivalent | result
'0' | 48 | '0' - '0' | 48 - 48 | 0
'1' | 49 | '1' - '0' | 49 - 48 | 1
'2' | 50 | '2' - '0' | 50 - 48 | 2
'3' | 51 | '3' - '0' | 51 - 48 | 3
'4' | 52 | '4' - '0' | 52 - 48 | 4
'5' | 53 | '5' - '0' | 53 - 48 | 5
'6' | 54 | '6' - '0' | 54 - 48 | 6
'7' | 55 | '7' - '0' | 55 - 48 | 7
'8' | 56 | '8' - '0' | 56 - 48 | 8
'9' | 57 | '9' - '0' | 57 - 48 | 9

The ascii value for 0 is 48, for 1 its 49 and so on. Now in your program c[80] is an array of characters. So if you input 1 from the keyboard, the compiler treats it as 49 (the ascii value) for the arithmetic operation. That's why we need to subtract the ascii value of 0 (i.e 48) to get the integer equivalent. this can be achieved either by subtracting '0' from the character or by subtracting 48 directly.
e.g. if you replace sum += c[i]-'0'; by sum += c[i]-48;, the code will also work. But this is not a good practice. Hope this helps.

Related

Typecasting char to int C++ [duplicate]

This question already has answers here:
Convert char to int in C and C++
(14 answers)
Closed last year.
I've found that when I typecast a character pointer to in C++17, I get a some sort of mapping instead of the actual number I would expect. Example below
#include <iostream>
int main () {
char c;
c = '1';
std::cout << int(c) << std::endl;
}
When I build and run this with
g++ file.cpp -o output
./output
I get
49
'0' maps to 48 and '2' maps to 50 and so on. Why? How do I avoid this?
What you are actually getting is the ASCII code for these characters because they are stored in memory as integers known as ASCII codes.
To convert a char variable to its decimal value instead you can use this:
int value = c - '0';
What this does is that it takes the integer value of c which is 48 for the '0' for example and subtracts the integer value of '0' from it which is also 48, resulting in 0.
Below is the full table for decimal digits and their corresponding ASCII values:
0 -> 48
1 -> 49
2 -> 50
3 -> 51
4 -> 52
5 -> 53
6 -> 54
7 -> 55
8 -> 56
9 -> 57
And when subtracting the '0' from them the result is their corresponding decimal values:
0 -> 48 - 48 = 0
1 -> 49 - 48 = 1
2 -> 50 - 48 = 2
3 -> 51 - 48 = 3
4 -> 52 - 48 = 4
5 -> 53 - 48 = 5
6 -> 54 - 48 = 6
7 -> 55 - 48 = 7
8 -> 56 - 48 = 8
9 -> 57 - 48 = 9
I've found that when I typecast a character pointer to in C++17, I get
a some sort of mapping instead of the actual number
In the provided code there are no pointers. There is an object of the type char.
char c;
c = '1';
This statement
std::cout << int(c) << std::endl;
outputs the internal representation of the character '1' as an integer. In ASCII the internal representation of the character '1' is decimal 49. In EBCDIC the internal representation of the character '1' is 241.
If you want to get the integer number 1 you could write for example
std::cout << c - '0' << std::endl;
Or you could output the character as character and the output on the console will be the same that is 1
std::cout << c << std::endl;

2nd Variation on Caesar Cipher (Having problems with splitting final string into parts)

Prompt:
In this country soldiers are poor but they need a certain level of secrecy for their communications so, though they do not know Caesar cypher, they reinvent it in the following way.
They use ASCII, without really knowing it, but code only letters a-z and A-Z. Other characters are kept such as.
They change the "rotate" each new message. This "rotate" is a prefix for their message once the message is coded. The prefix is built of 2 letters, the second one being shifted from the first one by the "rotate", the first one is the first letter, after being downcased, of the uncoded message.
For example if the "rotate" is 2, if the first letter of the uncoded message is 'J' the prefix should be 'jl'.
To lessen risk they cut the coded message and the prefix in five pieces since they have only five runners and each runner has only one piece.
If possible the message will be evenly split between the five runners; if not possible, parts 1, 2, 3, 4 will be longer and part 5 shorter. The fifth part can have length equal to the other ones or shorter. If there are many options of how to split, choose the option where the fifth part has the longest length, provided that the previous conditions are fulfilled. If the last part is the empty string don't put this empty string in the resulting array.
For example, if the coded message has a length of 17 the five parts will have lengths of 4, 4, 4, 4, 1. The parts 1, 2, 3, 4 are evenly split and the last part of length 1 is shorter. If the length is 16 the parts will be of lengths 4, 4, 4, 4, 0. Parts 1, 2, 3, 4 are evenly split and the fifth runner will stay at home since his part is the empty string and is not kept.
Could you ease them in programming their coding?
Example with shift = 1 :
message : "I should have known that you would have a perfect answer for me!!!"
code : => ["ijJ tipvme ibw", "f lopxo uibu z", "pv xpvme ibwf ", "b qfsgfdu botx", "fs gps nf!!!"]
By the way, maybe could you give them a hand to decode?
//Ends here
Issues faced:
Can't figure out how to divide the encoded string according to the given conditions. I understand the math behind how the division needs to be done, but can't convert it into code. I know that the num variable that I used needs to be decremented by 4 and the count variable should be incremented by 4 till the condition (num/4 > count) because the condition is such that if the string can be split in multiple ways, then we should do it such that the 5th part is of the longest length.
My code:
static vector<string> encodeStr(const string &s, int shift)
{
char pre = tolower(s[0]);
pre += shift;
string newS = "";
newS += tolower(s[0]);
newS += pre;
vector<string> ans;
for (int i = 0; i < (int)s.size(); i++)
{
if ((s[i] >= 65 && s[i] <= 90) || (s[i] >= 97 && s[i] <= 122))
{
char c = s[i];
c += shift;
newS += c;
}
else
newS.push_back(s[i]);
}
if (newS.size() % 4 == 0)
{
int parts = newS.size() / 4;
int start = 0;
while (start < (int)newS.size())
{
ans.push_back(newS.substr(start, parts));
start += parts;
}
}
else if (newS.size() % 5 == 0)
{
int parts = newS.size() / 5;
int start = 0;
while (start < (int)newS.length())
{
ans.push_back(newS.substr(start, parts));
start += parts;
}
}
else if (newS.length() % 5 != 0 && newS.length() % 4 != 0)
{
int num = newS.length();
int count = 0;
int start = 0;
while (num % 4 != 0)
{
num--;
count++;
}
while (num / 4 > count)
{
num = num - 4;
count = count + 4;
}
int x = newS.length() - count;
int parts = x / 4;
while (start < (int)newS.length() - count)
{
ans.push_back(newS.substr(start, parts));
start += parts;
}
ans.push_back(newS.substr((int)newS.size() - count, count));
}
return ans;
}
static string decode(vector<string> &s)
{
string s1 = "";
char check = ' ' - 1;
for (int i = 0; i < (int)s.size(); i++)
{
s1 += s[i];
}
char a = s1[1];
char b = s1[0];
int shift = a - b;
s1.erase(0, 2);
transform(s1.begin(), s1.end(), s1.begin(), [&](auto x)
{
if ((x >= 65 && x <= 90) || (x >= 97 && x <= 122))
return x -= shift;
else
return x;
});
for (int i = 0; i < (int)s1.size(); i++)
{
if (s1[i] == check)
{
s1[i]++;
}
}
return s1;
}
Code Output
First, we need to extract the important requirements from the story-text. An evaluation of the text leads to:
Caesar cypher
Based on ASCII
only upper and lowercase alpha letters shall be encoded ('A'-'Z', 'a'-'z')
The key (shift-information) shall be encoded and transmitted by along the message as 2 letter prefix. Taking the first letter of the text, unencrypted, as part 1 of the encrypted key and shifting this letter by the key and transmit it as part 2.
If possible the message will be evenly split between the five runners; if not possible, parts 1, 2, 3, 4 will be longer and part 5 shorter. The fifth part can have length equal to the other ones or shorter.
The 2-letter encrypted key shall be a prefix for parts of the split message.
For the following design, we can derive 3 major blocks:
We need a Caesar Cypher encryption/decryption algorithm
The key encryption/decryption must be implemented
The original message must be split according to requirements.
Let us start with the design for the Caesar Cypher encryption/decryption algorithm. We will take advantage of the ASCII code, where all characters have a defined associated numerical value. Please see the table below for the printable characters:
Hex Dec Bin Hex Dec Bin Hex Dec Bin
20 32 00100000 # 40 64 01000000 ` 60 96 01100000
! 21 33 00100001 A 41 65 01000001 a 61 97 01100001
" 22 34 00100010 B 42 66 01000010 b 62 98 01100010
# 23 35 00100011 C 43 67 01000011 c 63 99 01100011
$ 24 36 00100100 D 44 68 01000100 d 64 100 01100100
% 25 37 00100101 E 45 69 01000101 e 65 101 01100101
& 26 38 00100110 F 46 70 01000110 f 66 102 01100110
' 27 39 00100111 G 47 71 01000111 g 67 103 01100111
( 28 40 00101000 H 48 72 01001000 h 68 104 01101000
) 29 41 00101001 I 49 73 01001001 i 69 105 01101001
* 2a 42 00101010 J 4a 74 01001010 j 6a 106 01101010
+ 2b 43 00101011 K 4b 75 01001011 k 6b 107 01101011
, 2c 44 00101100 L 4c 76 01001100 l 6c 108 01101100
- 2d 45 00101101 M 4d 77 01001101 m 6d 109 01101101
. 2e 46 00101110 N 4e 78 01001110 n 6e 110 01101110
/ 2f 47 00101111 O 4f 79 01001111 o 6f 111 01101111
0 30 48 00110000 P 50 80 01010000 p 70 112 01110000
1 31 49 00110001 Q 51 81 01010001 q 71 113 01110001
2 32 50 00110010 R 52 82 01010010 r 72 114 01110010
3 33 51 00110011 S 53 83 01010011 s 73 115 01110011
4 34 52 00110100 T 54 84 01010100 t 74 116 01110100
5 35 53 00110101 U 55 85 01010101 u 75 117 01110101
6 36 54 00110110 V 56 86 01010110 v 76 118 01110110
7 37 55 00110111 W 57 87 01010111 w 77 119 01110111
8 38 56 00111000 X 58 88 01011000 x 78 120 01111000
9 39 57 00111001 Y 59 89 01011001 y 79 121 01111001
: 3a 58 00111010 Z 5a 90 01011010 z 7a 122 01111010
; 3b 59 00111011 [ 5b 91 01011011 { 7b 123 01111011
< 3c 60 00111100 \ 5c 92 01011100 | 7c 124 01111100
= 3d 61 00111101 ] 5d 93 01011101 } 7d 125 01111101
> 3e 62 00111110 ^ 5e 94 01011110 ~ 7e 126 01111110
? 3f 63 00111111 _ 5f 95 01011111 Del 7f 127 01111111
We observe that upper- and lowercase numbers only differ in one bit, which is equal to a distance of 32. We will use this property later.
Then, now, let us come to the core algorithm. Shifting letters.
The biggest problems are potential overflows. So, we need to deal with that.
Then we need to understand what encryption and decryption means. If encryption will shift everthing one to the right, decryption will shift it back to left again.
So, with "def" and key=1, the encrpyted string will be "efg".
And decrpytion with key=1, will shift it to left again. Result: "def"
We can observe that, for decryption, we simply need to shift by -1, so the negative of the key.
Important result: Encryption and decryption can be done with the same routine. We just need to invert the keys.
Let us look now at the overflow problematic. For the moment we will start with uppercase characters only. Characters have an associated code as shown in above ASCII table. For example, the letter 'A' is encoded with 65, 'B' with 66 and so on. Because we do not want to calculate with such big numbers, we normalize them. We simply subtract 'A' from each character. Then
'A' - 'A' = 0
'B' - 'A' = 1
'C' - 'A' = 2
'D' - 'A' = 3
You see the pattern. If we want to encrypt now the letter 'C' with key 3, we can do the following.
'C' - 'A' + 3 = 5 Then we add again 'A' to get back the letter and we will get 5 + 'A' = 'F'
That is the whole magic.
But what to do with an overflow, beyond 'Z'. This can be handled by a simple modulo division. Let us look at 'Z' + 1. We do 'Z' - 'A' = 25, then +1 = 26 and now, modulo 26 = 0. At the end again plus 'A' will be 'A'.
And so on and so on. The resulting formula is: (c - 'A' + key) % 26 +'A'
Next, what with negative keys? This is also simple. Assume an 'A' and key=-1.
Result will be a 'Z'. But this is the same as shifting positions 25 to the right. So, we can simply convert a negative key to a positive shift. The simple statement will be:
if (key < 0) key = (26 + (key % 26)) % 26;
With the above formular, there is even no need to check for a negative values. It will work for positive and negative values.
So, key = (26 + (key % 26)) % 26; will always work, for encrpytion and decrytion, for positive and negative keys.
Some extended information: Please have a look at any ASCII table and remeber, what we said above. We found out already, that any uppercase and lowercase character differ by 32. Or, if you look again to the binary representation:
char dec bin char dec bin
'A' 65 0100 0001 'a' 97 0110 0001
'B' 66 0100 0010 'b' 98 0110 0010
'C' 67 0100 0011 'b' 99 0110 0011
. . .
So, if you already know that a character is alpha, then the only difference between upper- and lowercase is bit number 5. If we want to know, if char is lowercase, we can get this by masking this bit. c & 0b0010 0000. Which is equal to c & 32 or c & 0x20.
If we want to operater on either uppercase or lowercase characters, then we can mask the "case" away. With c & 0b00011111 or c & 31 or c & 0x1F we will get always equivalents for uppercase charcters, already normalized to start with value 1.
char dez bin Masking char dez bin Masking
'A' 65 0100 0001 & 0x1b = 1 'a' 97 0110 0001 & 0x1b = 1
'B' 66 0100 0010 & 0x1b = 2 'b' 98 0110 0010 & 0x1b = 2
'C' 67 0100 0011 & 0x1b = 3 'b' 99 0110 0011 & 0x1b = 3
. . .
So, if we use an alpha character, mask it, and subtract 1, then we get as a result 0..25 for any upper- or lowercase character.
Again, I would like tor repeat the key handling. Positive keys will encrypt a string, negative keys will decrypt a string. But, as said above, negative keys can be transformed into positive ones. Example:
Shifting by -1 is same as shifting by +25
Shifting by -2 is same as shifting by +24
Shifting by -3 is same as shifting by +23
Shifting by -4 is same as shifting by +22
So,it is very obvious that we can calculate an always positive key by: 26 + key. For negative keys, this will give us the above offsets.
And for positve keys, we would have an overflow over 26, which we can elimiate by a modulo 26 division:
'A'--> 0 + 26 = 26 26 % 26 = 0
'B'--> 1 + 26 = 27 27 % 26 = 1
'C'--> 2 + 26 = 28 28 % 26 = 2
'D'--> 3 + 26 = 29 29 % 26 = 3
--> (c + key) % 26 will eliminate overflows and result in the correct new en/decryptd character.
And, if we combine this with the above wisdom for negative keys, we can write: ((26+(key%26))%26) which will work for all positive and negative keys.
If we now implement all above gathered wisdom in code, we can come up with bascically one C++ statement for the whole encryption and decryption, using std::transform:
std::string caesar(const std::string& in, int key) {
std::string res(in.size(), ' ');
std::transform(in.begin(), in.end(), res.begin(), [&](char c) {return std::isalpha(c) ? (char)((((c & 31) - 1 + ((26 + (key % 26)) % 26)) % 26 + 65) | (c & 32)) : c; });
return res;
}
This will do, what we described above:
(c & 31) - 1 will normalize a character. Meaning, convert to uppercase and to a range of 0-25
((26 + (key % 26)) % 26)) % 26 will do the key shift.
+ 65 will convert the nomalized value (0-25) back to a letter ('A'-'Z')
| (c & 32)) : c This will restore the lower case, if the letter was lower case before.
Now, we derived a complete algorithm and function for encryption and decryption using Caeser Cypher.
.
Next is splitting up the message in 5 parts.
The requirement was:
If possible the message will be evenly split between the five runners; if not possible, parts 1, 2, 3, 4 will be longer and part 5 shorter. The fifth part can have length equal to the other ones or shorter.
This can again be achieved with integer and modulo division. Basically, we will do an integer division to get the number of letters for each of the 5 chunks. Then we use a modulo division, to get the rest.
It is clear, but I will repeat it. If we do an integer division by 5, then the rest can be max 4. And this rest can then be distributed and added 1 by one to other chunks. Let us make an example using 23.
23 % 5 = 4 So, initially each chunk will be 4 letters long
Chunk 1: 4
Chunk 2: 4
Chunk 3: 4
Chunk 4: 4
Chunk 5: 4
------------
Sum: 20 // The rest, 3 is missing
Rest can be calculated with:
23 % 5 = 3 // So, we have a rest or remainder of 3. This we will distribute now:
Remainder = 3
Chunk 1: 4 + 1 = 5 3 - 1 = 2
Chunk 2: 4 + 1 = 5 2 - 1 = 1
Chunk 3: 4 + 1 = 5 1 - 1 = 0 Now everything was distributed
Chunk 4: 4 4
Chunk 5: 4 4
-------------------
Sum: 23
We now know, how chunksizes can be calculated.
For splitting the original strings into substrings, we can use the corresponding std::strings substr function, which is described here. You see, that we need to calculate a "start position" and a "length" value. Let us write a short piece of code for that.
#include <iostream>
#include <array>
#include <string>
constexpr std::size_t NumberOfChunks = 5u;
struct SDefs {
struct SDef {
std::size_t startPosition{}; // For substr function, we need a start position
std::size_t count{}; // and a count aof characters
};
std::array<SDef, NumberOfChunks> sDefs{}; // We have an array of 5 for this Positions and Counts
void calculate(const std::string& s) { // Calculation function
const size_t chunk = s.size() / NumberOfChunks; // Calculate the basic chunksize of all chunks
size_t remainder = s.size() % NumberOfChunks; // Calculate the rest that needs to be distributed
for (std::size_t startPos{}; SDef & sdef : sDefs) { // Calculate all positions and counts in a loop
sdef.startPosition = startPos; // Set startposition
sdef.count = chunk + (remainder ? 1 : 0); // And the chunk size, including potential distributed remainder
startPos += sdef.count; // Next startposition
if (remainder) --remainder; // And next remainder, if any
}
}
SDef& operator[](const std::size_t i) { return sDefs[i]; } // Easier accessibility
};
// Test code
int main () {
SDefs sdefs{};
std::string test{ "12345678901234567890123" };
sdefs.calculate(test);
for (std::size_t i{}; i < NumberOfChunks; ++i)
std::cout << "Chunk " << i+1 << " Start position: " << sdefs[i].startPosition << "\tCount: " << sdefs[i].count << '\n';
}
.
Finally: The transmission of the key. For encrypting, we simply take the first character of the text, or, in our case the substring. and then apply the encryption/decryption function on that to get the second letter.
And because the requirement was to use lower case characters, we set the 5th bit for the characters.
For decryption, in order to get the key, we need to subtract the second letter from the first. Thats all. Then we can invert it and use our encryption/decryption function again.
By the way. This method is dangerous and easy to hack, because you have always repeating letters at the beginning of a chunk.
For the final result, we need to add a little bit of house keeping code.
Then, lets_put everything together and create some program:
#include <iostream>
#include <array>
#include <string>
#include <algorithm>
#include <cctype>
constexpr std::size_t NumberOfChunks = 5u; // Maybe modified to whatever you need
// ---------------------------------------------------------------------------------------------------------
// Chunk calculator
struct SDefs {
struct SDef {
std::size_t startPosition{}; // For substr function, we need a start position
std::size_t count{}; // and a count aof characters
};
std::array<SDef, NumberOfChunks> sDefs{}; // We have an array of 5 for this Positions and Counts
void calculate(const std::string& s) { // Calculation function
const size_t chunk = s.size() / NumberOfChunks; // Calculate the basic chunksize of all chunks
size_t remainder = s.size() % NumberOfChunks; // Calculate the rest that needs to be distributed
for (std::size_t startPos{}; SDef & sdef : sDefs) { // Calculate all positions and counts in a loop
sdef.startPosition = startPos; // Set startposition
sdef.count = chunk + (remainder ? 1 : 0); // And the chunk size, including potential distributed remainder
startPos += sdef.count; // Next startposition
if (remainder) --remainder; // And next remainder, if any
}
}
SDef& operator[](const std::size_t i) { return sDefs[i]; } // Easier accessibility
};
// ---------------------------------------------------------------------------------------------------------
// Caesar Cypher
std::string caesar(const std::string& in, int key) {
std::string res(in.size(), ' ');
std::transform(in.begin(), in.end(), res.begin(), [&](char c) {return std::isalpha(c) ? (char)((((c & 31) - 1 + ((26 + (key % 26)) % 26)) % 26 + 65) | (c & 32)) : c; });
return res;
}
// Get a prefix, based on a given key
std::string getKeyPrefix(const std::string& s, const int key) {
std::string prefix("AA");
if (auto i = std::find_if(s.begin(), s.end(), std::isalpha); i != s.end()) {
prefix[0] = *i |32;
prefix[1] = (char)((((*i & 31) - 1 + ((26 + (key % 26)) % 26)) % 26 + 65) | 32);
}
return prefix;
}
// ---------------------------------------------------------------------------------------------------------
std::string test{"This was a major hack. What a pity that nobody will read or value it."};
int main() {
std::cout << "\nPlease enter a key: ";
if (int key{}; std::cin >> key) {
// Here we will store our encrypter and later decypted messages
std::array<std::string, NumberOfChunks> messages{};
// Here we will calculate the substrings properties
SDefs sdef{};
sdef.calculate(test);
// Encryption
for (std::size_t i{}; std::string& message : messages) {
// Get substring
const std::string sub = test.substr(sdef[i].startPosition, sdef[i].count);
// Encrypt sub string text
message = getKeyPrefix(sub, key) + caesar(sub,key);
// Debug output
std::cout << "Encrypted Message chunk " << i++ << ":\t" << message << '\n';
}
// Decryption
std::cout << "\n\nDecrypted Message:\n\n";
for (std::string& message : messages) {
// get key, inverted
int dkey = message[0] - message[1];
// Get substring
std::string sub = message.substr(2);
// Derypt sub string text
message = caesar(sub, dkey);
// Debug output
std::cout << message;
}
std::cout << "\n\n";
}
else
std::cerr << "\n\n***Error: Invalid input\n\n";
}
Have fun.
Checksum: fkems hajk eks ἀρμιν μοντιγνι qod krtd ghja

Maximize the summation Operation

Given an array of n numbers and integer k and m. We have to select subsequence of length k of the array. given a function s = summation from i=1 to i=k A(i)*(i mod m). We have to maximise s.
Constraints
n<10000
k<1000
|A(i)| < 10000000
m<10000000
Suppose array is 4 9 8 2 6 7 4. And k is 4 and m is 3. For this case answer is 32. ( 9*1 + 8*2 + 2*0 + 7*1 )
My code:
#include<bits/stdc++.h>
using namespace std;
#define ll long long int
#define g_long long long
#define maxx(a, b) a > b ? a : b
int main()
{
ll n, k, m, i, j;
cin >> n >> k >> m;
ll arr[n + 1] =
{ 0 };
for (i = 0; i < n; i++)
{
cin >> arr[i];
}
ll data[8][8] =
{ 0 };
for (i = 1; i <= k; ++i)
{
for (j = 1; j <= 7; ++j)
{
ll ans = maxx((data[i - 1][j - 1] + (arr[j - 1] * (i % m))),
(data[i][j - 1]));
data[i][j] = ans;
}
}
cout << data[k][n];
}
My approach is to first generate a subsequence of length k than keep on updating maximum value.
This code passes some of the test cases but some are giving wrong answer.
Can anyone help me what I am doing wrong in my code or suggest a better approach for this question?
The 2-D Dimensional Dp table which we are going to form by the following observation:
We have to take the maximum between the two values: (dp[i-1][j-1]+(arr[j-1]*(i%m)),dp[i][j-1])
where arr is the array i.e. [4 9 8 2 6 7 4] and dp is 2-dimensional DP-Table.
DP Table is given with rows as values of k (from 0 to k) and with columns as elements of the array.
DP| 0 | 4 | 09 | 08 | 02 | 06 | 07 | 04
00 || 0 | 0 | 00 | 00 | 00 | 00 | 00 | 00
01 || 0 | 4 | 09 | 09 | 09 | 09 | 09| 09
02 || 0 | 0 | 22 | 25 | 25 | 25 | 25| 25
03 || 0 | 0 | 00 |22 | 25 | 25 | 25| 25
04 || 0 | 0 | 00 |00 | 24 | 26 | 32 | 32
The following python code passes all the test cases as discussed in comments:
n = 7
k = 4
m = 3
arr = [49999, 4999, 4999, 4999, 99999, 99999, 49999]
# Initialising 2-D DP with 0 of size (k+1)*(n+1)
# Extra rows for handling edge cases
dp = [[0 for i in range(n+1)] for j in range(k+1)]
for i in range(1,k+1):
for j in range(i,n+1):
ans = max(dp[i-1][j-1]+(arr[j-1]*(i%m)),dp[i][j-1])
dp[i][j] = ans
# Maximum element at the bottom-right-most of 2-D DP
print(dp[k][n])
Thanks to #MBo for sharing top-down approach...
#functools.lru_cache
def mx(i, k):
if (i < 0 or k == 0):
return 0
else:
return max(mx(i-1, k), (mx(i-1, k-1) + l[i]*(k%m)))

Bit order in struct is not what I would have expected

I have a framework which uses 16 bit floats, and I wanted to separate its components to then use for 32bit floats. In my first approach I used bit shifts and similar, and while that worked, it was wildly chaotic to read.
I then wanted to use custom bit sized structs instead, and use a union to write to that struct.
The code to reproduce the issue:
#include <iostream>
#include <stdint.h>
union float16_and_int16
{
struct
{
uint16_t Mantissa : 10;
uint16_t Exponent : 5;
uint16_t Sign : 1;
} Components;
uint16_t bitMask;
};
int main()
{
uint16_t input = 0x153F;
float16_and_int16 result;
result.bitMask = input;
printf("Mantissa: %#010x\n", result.Components.Mantissa);
printf("Exponent: %#010x\n", result.Components.Exponent);
printf("Sign: %#010x\n", result.Components.Sign);
return 0;
}
In the example I would expect my Mantissa to be 0x00000054, the exponent to be 0x0000001F, and sign 0x00000001
Instead I get Mantissa: 0x0000013f, Exponent: 0x00000005, Sign: 0x00000000
Which means that from my bit mask first the Sign was taken (first bit), next 5 bits to exponent, then 10 bit to mantissa, so the order is inverse of what I wanted. Why is that happening?
The worse part is that a different compiler could give the expected order. The standard has never specified the implementation details for bitfields, and specifically the order. The rationale being as usual that it is an implementation detail and that programmers should not rely nor depend on that.
The downside is that it is not possible to use bitfields in cross language programs, and that programmers cannot use bitfields for processing data having well known bitfields (for example in network protocol headers) because it is too complex to make sure how the implementation will process them.
For that reason I have always thought that it was just an unuseable feature and I only use bitmask on unsigned types instead of bitfields. But that last part is no more than my own opinion...
I would say your input is incorrect, for this compiler anyway. This is what the float16_and_int16 order looks like.
sign exponent mantissa
[15] [14:10] [9:0]
or
SGN | E X P O N E N T| M A N T I S S A |
15 | 14 | 13 | 12 | 11 | 10 | 09 | 08 | 07 | 06 | 05 | 04 | 03 | 02 | 01 | 00 |
if input = 0x153F then bitMask ==
SGN | E X P O N E N T| M A N T I S S A |
15 | 14 | 13 | 12 | 11 | 10 | 09 | 08 | 07 | 06 | 05 | 04 | 03 | 02 | 01 | 00 |
0 0 0 1 0 1 0 1 0 0 1 1 1 1 1 1
so
MANTISSA == 0100111111 (0x13F)
EXPONENT == 00101 (0x5)
SIGN == 0 (0x0)
If you want mantissa to be 0x54, exponent 0x1f and sign 0x1 you need
SGN | E X P O N E N T| M A N T I S S A |
15 | 14 | 13 | 12 | 11 | 10 | 09 | 08 | 07 | 06 | 05 | 04 | 03 | 02 | 01 | 00 |
1 1 1 1 1 1 0 0 0 1 0 1 0 1 0 0
or
input = 0xFC64

for loop with nested if is broken, and transfers all 1's instead of data to an array [duplicate]

This question already has answers here:
Can you use 2 or more OR conditions in an if statement? [duplicate]
(9 answers)
Closed 3 years ago.
after several hours of testing i have narrowed down the problem to a single for loop, instead of the for loop (line 64) with the nested if transferring the data from converMain[] to converMain1[] all the data is set to 1's, Ive gone through and everything else works fine, its just this for loop.
int converMain[14];
converMain1[0] = 1;
int g = 1;
for (int i = 1; i < 19; i++) {
if (i == 1 || 2 || 4 || 8) { //tests if we are on a parody bit
converMain1[i] = p[i]; //puts parody bit in Main1 array
g++; //this variable helps sync the bits in the
//right spot in the Main1 array
}
else {
converMain1[i] = converMain[i - g];
//puts binary stored in Main array into Main1 array with correct sync
}
}
Output:
0001011 h 1010011 e 1001111101111111101 0010 392953 104 101 00010111010011
parody bits ^^ ^ ^
0011011 l 0011011 l 1001111101111111101 0010 392953 108 108 00110110011011
parody bits ^^ ^ ^
1111011 o 1110111 w 1101011101111111101 1000 392939 111 119 11110111110111
parody bits ^^ ^ ^
1111011 o 0100111 r 1111011101111111101 1100 392943 111 114 11110110100111
parody bits ^^ ^ ^
0011011 l 0010011 d 1111111111111111101 1111 393215 108 100 00110110010011
parody bits ^^ ^ ^
1000010 ! 1000010 ! 1011011101111111101 0100 392941 33 33 10000101000010
parody bits ^^ ^ ^
we should expect the number on the far right to be strung along into
number here in the middle witht he arrows ignoring the arrows' positions since those are the parody bits and
just shifting over them before putting the rest of the array down.
if (i == 1 || 2 || 4 || 8) is always true.
if ((i == 1) || (2) || (4) || (8)) is how the compiler reads it, thus it stops at lest at 2 since it's true.
A natural solution would be if (i == 1 || i == 2 || i == 4 || i == 8) ....