Dividing a decoded value, not minus/removing the last digit - c#

I have a method where I decode some information from a file, when I attempt to divide the value decoded by 10, let's say, it removes the last digit.
private int DecodeInt(byte[] bytes, int start)
{
int r2 = 0;
byte ch1 = bytes[start];
byte ch2 = bytes[start + 1];
int result = ch2 + (ch1 * 256);
if (result > 32767)
{
r2 = 0;
}
else
{
r2 = result;
}
return r2;
}
I know the value displayed should be 39.5.
Label_1.Text = (DecodeInt(Rec, 22)).ToString(); // Displays 395
Label_1.Text = (DecodeInt(Rec, 22) / 10).ToString(); // Displays 39
I'm confused as to why it doesn't function... I'm sure it will be simple adjustment but it's driving me a little mad.

You are dividing an int with an int so result will be in int only. What you can do is :
Label_1.Text = (DecodeInt(Rec, 22) / 10.0).ToString();

I looked here for my solution: https://stackoverflow.com/a/661042/2952390
double result = (double)DecodeInt(Rec,20)/(double)10;
Much easier than I thought, of course.

Related

How to swap a 2 digit number and find the larger of the result?

I want to use the number 25 then swap the two digits (the 2 and the 5) and then compare the swapped number (52) to the first number (25). If the swapped number is bigger I get a true and if the swapped number is smaller than the first number I get a false.
Example of what I want:
Input:
25
Output:
True //Because 25 reversed is 52, so it´s bigger
This is what I've tried:
int firstdigit = num / 10;
int secondigit = num % 10;
string res = secondigit + firstdigit.ToString();
if(res > num)
{
return true;
}
return false;
The problem now is that the "if" is not working anymore because res is a string and num is an int, but when I make res an int then I cant add the first digit and second digit because it's obviously different if I do 5 + 2 with ints (7) or 5 + 2 with strings (52).
You need to construct the reversed int value and compare against that:
int firstdigit = num / 10;
int secondigit = num % 10;
int reversed = firstdigit + seconddigit * 10;
if (reversed > num)
...
If you look at the code above, you should see that it's just reversing the logic that you used to extract the first and second digits.
Nice solution.
Maybe that's enough for you
int firstdigit = num / 10;
int secondigit = num % 10;
if(secondigit > firstdigit)
{
return true;
}
return false;

Issue with implementing Rabin-Karp algorithm to search string in LeetCode 28 "implement strStr()" using C#

I implemented this algorithm to solve Leetcode's #28 question "implemment strStr()".
Problem description:
Implement strStr(),
Returns the index of the first occurrence of needle in haystack, or -1 if needle is not part of haystack.
My code was implemented based on http://www.geeksforgeeks.org/searching-for-patterns-set-3-rabin-karp-algorithm/ 's tutoril.
I found out that with different prime number I use to scale down the hash, the function could go wrong.
Here is my code:
public class Solution {
public int StrStr(string haystack, string needle) {
int len = needle.Length;
//2 special case
if (haystack.Length < len) return -1;
if (needle == "") return 0;
//base prime number used for rabin-karp's hash function
int basement = 101;
//prime number used to scale down the hash value
int prime = 101;
//the factor used to multiply with the character to be removed from the hash
int factor = (int)(Math.Pow(basement, needle.Length - 1)) % prime;
//get ascii value of the needle and the initial window
int needleHash = 0;
int windowHash = 0;
byte[] needleBytes = Encoding.ASCII.GetBytes(needle);
byte[] windowBytes = Encoding.ASCII.GetBytes(haystack.Substring(0, len));
//generate hash value for both
for (int i = 0; i < needle.Length; i++)
{
needleHash = (needleHash * basement + needleBytes[i]) % prime;
windowHash = (windowHash * basement + windowBytes[i]) % prime;
}
//loop to find match
bool findMatch = true;
for (int i = 0; i < haystack.Length - len + 1; i++){
//if hash value matches, incase the hash value are not uniq, iterate through needle and window
if(needleHash == windowHash){
findMatch = true;
for (int j = 0; j < len; j++)
{
if (needle[j] != haystack[i + j])
{
findMatch = false;
break;
}
}
if (findMatch == true) return i;
}
//move the sliding window and find the hash value for new window
if (i < haystack.Length - len){
byte removeByte = Encoding.ASCII.GetBytes(haystack.Substring(i, 1))[0];
byte addByte = Encoding.ASCII.GetBytes(haystack.Substring(i + len, 1))[0];
//function of rolling hash
windowHash = ((windowHash - removeByte * factor) * basement + addByte) % prime;
//ensure the window hash to be positive
if(windowHash < 0) windowHash += prime;
}
}
return -1;
}
}
With "prime" set to "101", this code passes all test. But if i change it to other prime number no matter smaller or larger (example: 17, 31, 103), it always failed at test "68/72" which
haystack = "baabbaaaaaaabbaaaaabbabbababaabbabbbbbab
babbbbbbabababaabbbbbaaabbbbabaababababbbaabbbbaaabbaaba
bbbaabaabbabbaaaabababaaabbabbababbabbaaabbbbabbbbabbabbaabbbaa";
needle = "bbaaaababa";
Thus I do believe my code have big issues that I could not detect. Why does that happen?
Two issues with your code:
basement should be set at 256 per the algorithm at the site you used as a reference. This value is the number of characters in the input alphabet.
Your computation of factor is not correct; you're casting to int before calculating the remainder. The Math.Pow operation results in a double value that is larger than Int32.MaxValue. When you cast to int before the modulo operation you truncate this value. You need to perform the modulo with the double value and then cast to int. The line should look like this:
int factor = (int)((Math.Pow(basement, needle.Length - 1)) % prime);
I tested your code with these modifications and the example given and it works for primes of 17, 31, 101 and 103.

Convert an integer to a binary string with leading zeros

I need to convert int to bin and with extra bits.
string aaa = Convert.ToString(3, 2);
it returns 11, but I need 0011, or 00000011.
How is it done?
11 is binary representation of 3. The binary representation of this value is 2 bits.
3 = 20 * 1 + 21 * 1
You can use String.PadLeft(Int, Char) method to add these zeros.
// convert number 3 to binary string.
// And pad '0' to the left until string will be not less then 4 characters
Convert.ToString(3, 2).PadLeft(4, '0') // 0011
Convert.ToString(3, 2).PadLeft(8, '0') // 00000011
I've created a method to dynamically write leading zeroes
public static string ToBinary(int myValue)
{
string binVal = Convert.ToString(myValue, 2);
int bits = 0;
int bitblock = 4;
for (int i = 0; i < binVal.Length; i = i + bitblock)
{ bits += bitblock; }
return binVal.PadLeft(bits, '0');
}
At first we convert my value to binary.
Initializing the bits to set the length for binary output.
One Bitblock has 4 Digits. In for-loop we check the length of our converted binary value und adds the "bits" for the length for binary output.
Examples:
Input: 1 -> 0001;
Input: 127 -> 01111111
etc....
You can use these methods:
public static class BinaryExt
{
public static string ToBinary(this int number, int bitsLength = 32)
{
return NumberToBinary(number, bitsLength);
}
public static string NumberToBinary(int number, int bitsLength = 32)
{
string result = Convert.ToString(number, 2).PadLeft(bitsLength, '0');
return result;
}
public static int FromBinaryToInt(this string binary)
{
return BinaryToInt(binary);
}
public static int BinaryToInt(string binary)
{
return Convert.ToInt32(binary, 2);
}
}
Sample:
int number = 3;
string byte3 = number.ToBinary(8); // output: 00000011
string bits32 = BinaryExt.NumberToBinary(3); // output: 00000000000000000000000000000011
public static String HexToBinString(this String value)
{
String binaryString = Convert.ToString(Convert.ToInt32(value, 16), 2);
Int32 zeroCount = Convert.ToInt32(Math.Ceiling(Convert.ToDouble(binaryString.Length) / 8)) * 8;
return binaryString.PadLeft(zeroCount, '0');
}
Just what Soner answered use:
Convert.ToString(3, 2).PadLeft(4, '0')
Just want to add just for you to know. The int parameter is the total number of characters that your string and the char parameter is the character that will be added to fill the lacking space in your string. In your example, you want the output 0011 which which is 4 characters and needs 0's thus you use 4 as int param and '0' in char.
string aaa = Convert.ToString(3, 2).PadLeft(10, '0');
This may not be the most elegant solution but it is the fastest from my testing:
string IntToBinary(int value, int totalDigits) {
char[] output = new char[totalDigits];
int diff = sizeof(int) * 8 - totalDigits;
for (int n = 0; n != totalDigits; ++n) {
output[n] = (char)('0' + (char)((((uint)value << (n + diff))) >> (sizeof(int) * 8 - 1)));
}
return new string(output);
}
string LongToBinary(int value, int totalDigits) {
char[] output = new char[totalDigits];
int diff = sizeof(long) * 8 - totalDigits;
for (int n = 0; n != totalDigits; ++n) {
output[n] = (char)('0' + (char)((((ulong)value << (n + diff))) >> (sizeof(long) * 8 - 1)));
}
return new string(output);
}
This version completely avoids if statements and therfore branching which creates very fast and most importantly linear code. This beats the Convert.ToString() function from microsoft by up to 50%
Here is some benchmark code
long testConv(Func<int, int, string> fun, int value, int digits, long avg) {
long result = 0;
for (long n = 0; n < avg; n++) {
var sw = Stopwatch.StartNew();
fun(value, digits);
result += sw.ElapsedTicks;
}
Console.WriteLine((string)fun(value, digits));
return result / (avg / 100);//for bigger output values
}
string IntToBinary(int value, int totalDigits) {
char[] output = new char[totalDigits];
int diff = sizeof(int) * 8 - totalDigits;
for (int n = 0; n != totalDigits; ++n) {
output[n] = (char)('0' + (char)((((uint)value << (n + diff))) >> (sizeof(int) * 8 - 1)));
}
return new string(output);
}
string Microsoft(int value, int totalDigits) {
return Convert.ToString(value, toBase: 2).PadLeft(totalDigits, '0');
}
int v = 123, it = 10000000;
Console.WriteLine(testConv(Microsoft, v, 10, it));
Console.WriteLine(testConv(IntToBinary, v, 10, it));
Here are my results
0001111011
122
0001111011
75
Microsofts Method takes 1.22 ticks while mine only takes 0.75 ticks
With this you can get binary representation of string with corresponding leading zeros.
string binaryString = Convert.ToString(3, 2);;
int myOffset = 4;
string modified = binaryString.PadLeft(binaryString.Length % myOffset == 0 ? binaryString.Length : binaryString.Length + (myOffset - binaryString.Length % myOffset), '0'));
In your case modified string will be 0011, if you want you can change offset to 8, for instance, and you will get 00000011 and so on.

Split number into groups of 3 digits

I want to make a method that takes a variable of type int or long and returns an array of ints or longs, with each array item being a group of 3 digits. For example:
int[] i = splitNumber(100000);
// Outputs { 100, 000 }
int[] j = splitNumber(12345);
// Outputs { 12, 345 }
int[] k = splitNumber(12345678);
// Outputs { 12, 345, 678 }
// Et cetera
I know how to get the last n digits of a number using the modulo operator, but I have no idea how to get the first n digits, which is the only way to make this method that I can think of. Help please!
Without converting to string:
int[] splitNumber(int value)
{
Stack<int> q = new Stack<int>();
do
{
q.Push(value%1000);
value /= 1000;
} while (value>0);
return q.ToArray();
}
This is simple integer arithmetic; first take the modulo to get the right-most decimals, then divide to throw away the decimals you already added. I used the Stack to avoid reversing a list.
Edit: Using log to get the length was suggested in the comments. It could make for slightly shorter code, but in my opinion it is not better code, because the intent is less clear when reading it. Also, it might be less performant due to the extra Math function calls. Anyways; here it is:
int[] splitNumber(int value)
{
int length = (int) (1 + Math.Log(value, 1000));
var result = from n in Enumerable.Range(1,length)
select ((int)(value / Math.Pow(1000,length-n))) % 1000;
return result.ToArray();
}
By converting into a string and then into int array
int number = 1000000;
string parts = number.ToString("N0", new NumberFormatInfo()
{
NumberGroupSizes = new[] { 3 },
NumberGroupSeparator = "."
});
By using Maths,
public static int[] splitNumberIntoGroupOfDigits(int number)
{
var numberOfDigits = Math.Floor(Math.Log10(number) + 1); // compute number of digits
var intArray = new int[Convert.ToInt32(numberOfDigits / 3)]; // we know the size of array
var lastIndex = intArray.Length -1; // start filling array from the end
while (number != 0)
{
var lastSet = number % 1000;
number = number / 1000;
if (lastSet == 0)
{
intArray[lastIndex] = 0; // set of zeros
--lastIndex;
}
else if (number == 0)
{
intArray[lastIndex] = lastSet; // this could be your last set
--lastIndex;
}
else
{
intArray[lastIndex] = lastSet;
--lastIndex;
}
}
return intArray;
}
Try converting it to string first and do the parsing then convert it back to number again
Convert to string
Get length
If length modulus 3 == 0
String substring it into ints every 3
else if
Find remainder such as one or two left over
Substring remainder off of front of string
Then substring by 3 for the rest
You can first find out how large the number is, then use division to get the first digits, and modulo to keep the rest:
int number = 12345678;
int len = 1;
int div = 1;
while (number >= div * 1000) {
len++;
div *= 1000;
}
int[] result = new int[len];
for (int i = 0; i < result.Length; i++) {
result[i] = number / div;
number %= div;
div /= 1000;
}
You can use this with the System.Linq namespace from .NET 3.5 and above:
int[] splitNumber(long value)
{
LinkedList<int> results = new LinkedList<int>();
do
{
int current = (int) (value % 1000);
results.AddFirst(current);
value /= 1000;
} while (value > 0);
return results.ToArray();// Extension method
}
I use LinkedList<int> to avoid having to Reverse a list before returning. You could also use Stack<int> for the same purpose, which would only require .NET 2.0:
int[] splitNumber(long value)
{
Stack<int> results = new Stack<int>();
do
{
int current = (int) (value % 1000);
results.Push(current);
value /= 1000;
} while (value > 0);
return results.ToArray();
}

Solving Mathematical logics, placing digits in third number from digits of first and second number

I have two numbers.
First Number is 2875 &
Second Number is 852145
Now I need a program which create third number.
Third Number will be 2885725145
The logic is
First digit of third number is first digit of first number.
Second digit of third number is first digit of second number.
Third digit of third number is second digit of first number.
Fourth digit of third number is second digit of second number;
so on.
If any number has remaining digits then that should be appended at last.
I do not want to convert int to string.
int CreateThirdNumber(int firstNumber, int secondNumber)
{
}
So can anyone suggest me any solution to this problem?
I do not want to convert int to string.
Why?
Without converting to string
Use Modulus and Division operator.
With converting to string
Convert them to string. Use .Substring() to extract and append value in a string. Convert appended string to integer.
Here's a bit that will give you a lead:
Say you have the number 2875. First, you need to determine it's length, and then, extract the first digit
This can be easily calculated:
int iNumber = 2875;
int i = 10;
int iLength = 0;
while (iNumber % i <= iNumber){
iLength++;
i *= 10;
}
// iNumber is of length iLength, now get the first digit,
// using the fact that the division operator floors the result
int iDigit = iNumber / pow(10, iLength-1);
// Thats it!
First a little advice: if you use int in C#, then the value in your example (2885725145) is bigger than int.MaxValue; (so in this case you should use long instead of int).
Anyway here is the code for your example, without strings.
int i1 = 2875;
int i2 = 852145;
int i3 = 0;
int i1len = (int)Math.Log10(i1) + 1;
int i2len = (int)Math.Log10(i2) + 1;
i3 = Math.Max(i1, i2) % (int)Math.Pow(10, Math.Max(i1len, i2len) - Math.Min(i1len, i2len));
int difference = (i1len - i2len);
if (difference > 0)
i1 /= (int)Math.Pow(10, difference);
else
i2 /= (int)Math.Pow(10, -difference);
for (int i = 0; i < Math.Min(i1len, i2len); i++)
{
i3 += (i2 % 10) * (int)Math.Pow(10, Math.Max(i1len, i2len) - Math.Min(i1len, i2len) + i * 2);
i3 += (i1 % 10) * (int)Math.Pow(10, Math.Max(i1len, i2len) - Math.Min(i1len, i2len) + i * 2 + 1);
i1 /= 10;
i2 /= 10;
}
I don't understand why you don't want to use strings (is it homework?). Anyway this is another possible solution:
long CreateThirdNumber(long firstNumber, long secondNumber)
{
long firstN = firstNumber;
long secondN = secondNumber;
long len1 = (long)Math.Truncate(Math.Log10(firstNumber));
long len2 = (long)Math.Truncate(Math.Log10(secondNumber));
long maxLen = Math.Max(len1, len2);
long result = 0;
long curPow = len1 + len2 + 1;
for (int i = 0; i <= maxLen; i++)
{
if (len1 >= i)
{
long tenPwf = (long)Math.Pow(10, len1 - i);
long firstD = firstN / tenPwf;
firstN = firstN % tenPwf;
result = result + firstD * (long)Math.Pow(10, curPow--);
}
if (len2 >= i)
{
long tenPws = (long)Math.Pow(10, len2 - i);
long secondD = secondN / tenPws;
result = result + secondD * (long)Math.Pow(10, curPow--);
secondN = secondN % tenPws;
}
}
return result;
}
This solves it:
#include <stdio.h>
int main(void)
{
int first = 2875,second = 852145;
unsigned int third =0;
int deci,evenodd ,tmp ,f_dec,s_dec;
f_dec = s_dec =1;
while(first/f_dec != 0 || second/s_dec != 0) {
if(first/f_dec != 0) {
f_dec *=10;
}
if( second/s_dec != 0) {
s_dec *= 10;
}
}
s_dec /=10; f_dec/=10;
deci = s_dec*f_dec*10;
evenodd =0;tmp =0;
while(f_dec != 0 || s_dec !=0 ) {
if(evenodd%2 == 0 && f_dec !=0 ) {
tmp = (first/f_dec);
first -=(tmp*f_dec);
tmp*=deci;
third+=tmp;
f_dec/=10;
deci/=10;
}
if(evenodd%2 != 0 && s_dec != 0) {
tmp= (second/s_dec);
second -=(tmp*s_dec);
//printf("tmp:%d\n",tmp);
tmp*=deci;
third += tmp;
s_dec/=10;
deci/=10;
}
evenodd++;
}
printf("third:%u\ncorrct2885725145\n",third);
return 0;
}
output:
third:2885725145
corrct2885725145
#include <stdio.h>
long long int CreateThirdNumber(int firstNumber, int secondNumber){
char first[11],second[11],third[21];
char *p1=first, *p2=second, *p3=third;
long long int ret;
sprintf(first, "%d", firstNumber);
sprintf(second, "%d", secondNumber);
while(1){
if(*p1)
*p3++=*p1++;
if(*p2)
*p3++=*p2++;
if(*p1 == '\0' && *p2 == '\0')
break;
}
*p3='\0';
sscanf(third, "%lld", &ret);
return ret;
}
int main(){
int first = 2875;
int second = 852145;
long long int third;
third = CreateThirdNumber(first, second);
printf("%lld\n", third);
return 0;
}

Categories

Resources