My task is to migrate this Java code to a C# version, but I'm having trouble with the ValueOf method, since I can't seem to find a equivalent version for C# (because of the Radix parameter used on Java, 16 in this case).
public String decrypt_string(String s)
{
String s1 = "";
int i = s.length() / 2;
int[] ai = new int[i];
for (int j = 0; j < i; j++)
{
// This is the "problematic" line \/
ai[j] = Integer.valueOf(s.substring(j * 2, j * 2 + 2), 16).intValue();
}
int[] ai1 = decrypt_block(ai, i);
for (int k = 0; k < i; k++)
{
if (ai1[k] != 0)
s1 = s1 + (char)ai1[k];
}
return s1;
}
Here is my try, but it failed:
public String decrypt_string(String s)
{
String s1 = "";
int i = s.Length / 2;
int[] ai = new int[i];
for (int j = 0; j < i; j++)
{
int startIndex = j * 2;
string tmp = s.Substring(startIndex, 2);
ai[j] = Int32.Parse (tmp);
}
int[] ai1 = decrypt_block(ai, i);
for (int k = 0; k < i; k++)
{
if (ai1[k] != 0)
s1 = s1 + (char)ai1[k];
}
return s1;
}
Thanks in advance
If you are trying to parse a hexadecimal (base-16) number, use this:
int.Parse (tmp, NumberStyles.HexNumber);
You need to convert a string to an integer, given that the string is in a specific base.
int i = Convert.ToInt32(str, 16);
int j = Convert.ToInt32("A", 16); // 10
So:
for (int j = 0; j < i; j++)
{
int startIndex = j * 2;
ai[j] = Convert.ToInt32(s.Substring(startIndex, 2));
}
The radix is on Integer.valueOf(), not s.substring() in the java code you show there, so this would become:
ai[j] = Int32.Parse(s.Substring(j * 2, j * 2 + 2), 16);
Related
I've read the CLRS and tried to implement the recursive merge sort algorithm . cant see what the error is but everytime i run it gives me an "Index out of bounds error "
i've been trying for 5h now
static public void MergeSort(int[] input, int IndexStanga, int IndexDreapta)
{
if (IndexStanga < IndexDreapta)
{
int IndexMijloc = (IndexDreapta + IndexStanga) / 2;
MergeSort(input, IndexStanga, IndexMijloc);
MergeSort(input, IndexMijloc + 1, IndexDreapta);
Merge(input, IndexStanga, IndexDreapta, IndexMijloc);
}
}
static public void Merge(int[] input, int stanga, int dreapta, int mijloc)
{
int lungDR = 0;
int lunST = 0;
lungDR = dreapta - mijloc;
lunST = mijloc - stanga + 1;
int[] valDreapta = new int[lungDR + 1];
int[] valStanga = new int[lunST + 1];
valDreapta[valDreapta.Length - 1] = int.MaxValue;
valStanga[valStanga.Length - 1] = int.MaxValue;
int i = 0;
int j = 0;
for (i = stanga; i <= mijloc; i++) valStanga[i] = input[i];
for (i = 0; i < lungDR; i++) { valDreapta[i] = input[i + mijloc + 1]; }
i = 0;
j = 0;
for (int k = 0; k < input.Length; k++)
{
if (valStanga[i] <= valDreapta[j]) //error out of bounds
{
input[k] = valStanga[i];
i++;
}
else
{
input[k] = valDreapta[j];
j++;
}
}
}
Fixes noted in comments below. First fix for moving data from input to valStanga. Second fix for the range on merging back to input. The parameters for merge are in an unusual order, first, last, middle. Normally the order is first, middle, last.
Comments: The program will have issues if the array to be sorted contains elements equal to max integer. It would be more efficient to do a one time allocation of a working array, rather than allocate new sub-arrays on every call to merge. The copy operations can be avoided by changing the direction of merge with each level of recursion.
int i = 0;
int j = 0;
for (i = 0; i < lungDR; i++) { valDreapta[i] = input[i + mijloc + 1]; }
for (i = 0; i < lunST; i++) { valStanga[i] = input[i + stanga]; } // fix
i = 0;
j = 0;
for (int k = stanga; k <= dreapta; k++) // fix
{
if (valStanga[i] <= valDreapta[j])
I have to write searching algorithm, For example I have to compare str="giorgi" to str2="grigol". I'm trying to find longest matching sequence of chars, so that the order of chars is the same and string which I should get is "grg"... with this c# code I'm getting "grig".
int k=0;
string s="";
string str = "giorgi";
string str2 = "grigol";
for(int i=0;i<str.Length;i++)
{
for (int j = k; j < str2.Length; j++)
{
if (str[i] == str2[j])
{
s += str2[k];
k++;
goto endofloop;
}
}
endofloop:;
}
Console.WriteLine(s);
The solution:
using System;
class GFG
{
/* Returns length of LCS for X[0..m-1], Y[0..n-1] */
static int lcs( char[] X, char[] Y, int m, int n )
{
int [,]L = new int[m+1,n+1];
/* Following steps build L[m+1][n+1]
in bottom up fashion. Note
that L[i][j] contains length of
LCS of X[0..i-1] and Y[0..j-1] */
for (int i = 0; i <= m; i++)
{
for (int j = 0; j <= n; j++)
{
if (i == 0 || j == 0)
L[i, j] = 0;
else if (X[i - 1] == Y[j - 1])
L[i, j] = L[i - 1, j - 1] + 1;
else
L[i, j] = GFG.max(L[i - 1, j], L[i, j - 1]);
}
}
return L[m, n];
}
static int max(int a, int b)
{
return (a > b)? a : b;
}
}
And now the program to test it:
public static void Main()
{
String s1 = "giorgi";
String s2 = "grigol";
char[] X=s1.ToCharArray();
char[] Y=s2.ToCharArray();
int m = X.Length;
int n = Y.Length;
Console.Write("Length of LCS is" + " " +lcs( X, Y, m, n ) );
}
}
The numbers are stored in the arrays with their digits in reverse order. Here is a functions that should multiply two numbers, lhs and rhs, and store the product in result:
public static void MultiplyDigitArrays(int[] lhs, int[] rhs, int[] result)
{
int length1 = Math.Max(lhs.Length, rhs.Length);
for (int i = 0; i < length1; i++)
{
int[] PartialProduct = new int[result.Length];
int length2 = Math.Min(lhs.Length, rhs.Length);
for (int j = 0; j < length2; j++)
{
int multiplicand = (lhs.Length < rhs.Length) ? rhs[i] : lhs[i];
int multiplier = (lhs.Length < rhs.Length) ? lhs[j] : rhs[j];
int product = PartialProduct[i + j] + multiplicand * multiplier;
PartialProduct[i + j] = product % 10;
int carry = product / 10;
PartialProduct[i + j + 1] = PartialProduct[i + j + 1] + carry;
}
SumDigitArrays(PartialProduct, result, result);
}
}
However, if I multiply:
static void Main(string[] args)
{
int[] n1 = { 1, 1 };
int[] n2 = { 1, 1 };
int[] result = new int[Math.Max(n1.Length, n2.Length) * 2 + 1];
MultiplyDigitArrays(n1, n2, result);
PrintArray(result);
Console.WriteLine();
}
the result is:
00132
instead of the expected:
00121
What am I doing wrong?
For the MCVE:
public static void PrintArray(int[] Array)
{
int length = Array.Length;
for (int i = length - 1; i >= 0; i--)
{
Console.Write(Array[i]);
}
}
public static void SumDigitArrays(int[] a, int[] b, int[] result)
{
int length = Math.Max(a.Length, b.Length);
for (int i = 0; i < length; i++)
{
int lhs = (i < a.Length) ? a[i] : 0;
int rhs = (i < b.Length) ? b[i] : 0;
int sum = result[i] + lhs + rhs;
result[i] = sum % 10;
int carry = sum / 10;
if (i + 1 < result.Length)
{
result[i + 1] = result[i + 1] + carry;
}
}
}
The reason is because the third parameter use you in calling SumDigitArrays should be empty. Instead, you feed it the result variable which contains data on any iteration other than the first.
Implement your method like this:
public static int[] MultiplyDigitArrays(int[] lhs, int[] rhs)
{
int length1 = Math.Max(lhs.Length, rhs.Length);
var result = new int[length1* length1];
for (int i = 0; i < length1; i++)
{
int[] PartialProduct = new int[length1 * length1];
int length2 = Math.Min(lhs.Length, rhs.Length);
for (int j = 0; j < length2; j++)
{
int multiplicand = (lhs.Length < rhs.Length) ? rhs[i] : lhs[i];
int multiplier = (lhs.Length < rhs.Length) ? lhs[j] : rhs[j];
int product = PartialProduct[i + j] + multiplicand * multiplier;
PartialProduct[i + j] = product % 10;
int carry = product / 10;
PartialProduct[i + j + 1] = PartialProduct[i + j + 1] + carry;
}
result = SumDigitArrays(PartialProduct, result);
}
return result;
}
public static int[] SumDigitArrays(int[] a, int[] b)
{
int length = Math.Max(a.Length, b.Length);
var result = new int[length];
for (int i = 0; i < length; i++)
{
int lhs = (i < a.Length) ? a[i] : 0;
int rhs = (i < b.Length) ? b[i] : 0;
int sum = result[i] + lhs + rhs;
result[i] = sum % 10;
int carry = sum / 10;
if (i + 1 < result.Length)
{
result[i + 1] = result[i + 1] + carry;
}
}
return result;
}
I don't exactly understand the logic you are performing, but
int product = PartialProduct[i + j] + multiplicand * multiplier;
Gets evaluated as
int product = PartialProduct[i + j] + (multiplicand * multiplier);
Did you intend it to do
int product = (PartialProduct[i + j] + multiplicand) * multiplier;
As that could explain your error.
Apart from the two other answers given (which are spot-on and solve your problem), unless you have a very specific need, I'd recommend going for BigInteger if you need to multiply very large numbers.
For your specific needs (in case your numbers must come and go in an array of ints, which is a weird way to store any number), your Multiply could become:
public static void MultiplyDigitArrays(int[] lhs, int[] rhs, int[] result)
{
var n1 = BigInteger.Parse(string.Join("", lhs));
var n2 = BigInteger.Parse(string.Join("", rhs));
var resultBi = BigInteger.Multiply(n1, n2);
Array.Clear(result, 0, result.Length);
var stResult = resultBi.ToString().PadLeft(result.Length, '0');
for(int i = 0; i < stResult.Length; i++)
{
result[(stResult.Length-1)-i] = int.Parse(stResult[i].ToString());
}
}
Note that the burden of this function is actually converting your integer array back and forth, since an integer array is a weird format to store a number.
If you work directly with strings (or BigIntegers), this function would just not be necessary. For example, if working with strings containing the numbers, this could become:
public static string MultiplyBigNumbers(string lhs, string rhs)
{
var n1 = BigInteger.Parse(lhs);
var n2 = BigInteger.Parse(rhs);
return BigInteger.Multiply(n1, n2).ToString();
}
And just call it: MultiplyBigNumbers("3242", "42349");
Then again, I'd recommend just working with BigInteger all the way down, and have it converted whenever you need to store it (for which a byte array makes more sense, and you can get it with ToByteArray()) or display (which can be easily done with a ToString() call)
Note that passing an array for the result is also pretty weird (for .NET anyway), since you don't need the original values. You'd be better off returning an array and calculating the needed length in the function itself, not having the caller figure it out.
I'm trying to make a program that: When given a 4 digit number (for example, 1001) it sums the digits of that number, for 1001 this is 1 + 0 + 0 + 1 = 2, than it finds all sequences of 6 numbers from 1 to 6 (including permutations, i.e. 1*1*1*1*1*2 is different than 2*1*1*1*1*1) whose product is that number.
The result should be printed on the console in the following format: each sequence of 6 numbers, with their Morse representation, separated with a single pipe: 1 is .---- , 2 is ..---: .----|.----|.----|.----|..---|, on a new row the next permutation: .----|.----|.----|..---|.----| and so on.
The problem is, my solution doesn't show the correct answers, not even the correct number of them.
Here's my code (and please, if possible, tell me where my mistake is, and not some one line hack solutions to the problem with LINQ and regex and God knows what):
string n = Console.ReadLine();
string[] digitsChar = new string[n.Length];
for (int i = 0; i < 4; i++)
{
digitsChar[i] = n[i].ToString();
}
int[] digits = new int[digitsChar.Length];
for (int i = 0; i < 4; i++)
{
digits[i] = Convert.ToInt32(digitsChar[i]);
}
int morseProduct = digits.Sum();
Console.WriteLine(morseProduct);
List<int> morseCodeNumbers = new List<int>();
for (int i = 1; i < 6; i++)
{
for (int j = 1; i < 6; i++)
{
for (int k = 1; i < 6; i++)
{
for (int l = 1; i < 6; i++)
{
for (int m = 1; i < 6; i++)
{
for (int o = 1; o < 6; o++)
{
int product = i * j * k * l * m * o;
if (product == morseProduct)
{
morseCodeNumbers.Add(i);
morseCodeNumbers.Add(j);
morseCodeNumbers.Add(k);
morseCodeNumbers.Add(l);
morseCodeNumbers.Add(m);
morseCodeNumbers.Add(o);
}
}
}
}
}
}
}
int numberOfNumbers = morseCodeNumbers.Count;
string[] morseCodes = new string[] { "-----", ".----", "..---", "...--", "....-", "....." };
for (int i = 0; i < numberOfNumbers; i++)
{
int counter = 0;
if (i % 5 == 0)
{
Console.WriteLine();
counter = 0;
}
if (counter < 5)
{
int index = morseCodeNumbers[i];
Console.Write(morseCodes[index] + "|");
counter++;
}
A lot of your for-loop conditions refer to i instead of j,k,l and m. The same for the increment part. For example:
for (int j = 1; i < 6; i++)
should be
for (int j = 1; j < 6; j++)
Furthermore if the range is from 1 to 6 you need to change < to <=, see:
for (int i = 1; i <= 6; i++)
You don't need to convert the string to a string array to get the int array of digits btw, so while this is correct:
for (int i = 0; i < 4; i++)
{
digitsChar[i] = n[i].ToString();
}
int[] digits = new int[digitsChar.Length];
for (int i = 0; i < 4; i++)
{
digits[i] = Convert.ToInt32(digitsChar[i]);
}
you could it do like that (sry for LINQ):
var digits = n.Select(c=>(int)char.GetNumericValue(c) ).ToArray();
I'm trying to convert this MATLAB function into c#
but my results are not as expected.
MATLAB:
function check=CRC8(xa);
% xa is array of bits to be transmitted (column vector)
% Generates 8-bit CRC check with g(x) = x^8 + x^2 +x + 1
xae = [xa;0;0;0;0;0;0;0;0]; % Append 8 zeros to array containing bit-stream
g8x = [1;0;0;0;0;0;1;1;1] ; % Generator polynomial
xsa=xae(1:9);
for i=1:length(xa)
if xsa(1) = = g8x(1), xsa = xor(xsa,g8x); end;
xsa(1:8)=xsa(2:9);
if i<length(xa) xsa(9)=xae(i+9); end;
end;
check = xsa(1:8); % 8 bit CRC column vector
return;
C#
public static int[] checkCRC8(int[] xa)
{
int[] g8x = { 1, 0, 0, 0, 0, 0, 1, 1, 1 };
int[] xae = new int[xa.Length + 8];
xa.CopyTo(xae, 0);
//add zeros
for (int i = xa.Length; i < xae.Length; i++)
{
xae[i] = 0;
}
int[] xsa = new int[8];
for (int i = 0; i < 8; i++)
{
xsa[i] = xae[i];
}
for (int i = 0; i < xa.Length; i++)
{
if (xsa[0] == g8x[0])
{
//xor xsa with g8x
for (int j = 0; j < xsa.Length; j++)
{
xsa[j] = xsa[j] ^ g8x[j];
}
}
//shift array elements left
for (int j = 0; j < xsa.Length - 1; j++)
{
xsa[j] = xsa[j + 1];
}
if (i < xa.Length)
{
xsa[xsa.Length - 1] = xae[i + 8];
}
}
return xsa;
}
}
The matlab ranges like in xsa = xae(1:9) are inclusive, so xsa should have nine elements instead of eight. Also, since your i is already zero based, I think the last if should compare against xa.Length-1 and use the array element at i+9 instead of i+8:
if (i < xa.Length - 1)
{
xsa[xsa.Length - 1] = xae[i + 9];
}