How to transform C# byte[] to struct[] - c#

In C# I have a struct like this:
[StructLayout(LayoutKind.Sequential,Size = 3)]
public struct int24
{
private byte a;
private byte b;
private byte c;
public int24(byte a, byte b, byte c)
{
this.a = a;
this.b = b;
this.c = c;
}
public Int32 getInt32()
{
byte[] bytes = {this.a, this.b, this.c , 0};
// if we want to put the struct into int32, need a method, not able to type cast directly
return BitConverter.ToInt32(bytes, 0);
}
public void display()
{
Console.WriteLine(" content is : " + a.ToString() + b.ToString() + c.ToString());
}
}
For byte[] to struct[] transformation, I use:
public static int24[] byteArrayToStructureArrayB(byte[] input) {
int dataPairNr = input.Length / 3;
int24[] structInput = new int24[dataPairNr];
var reader = new BinaryReader(new MemoryStream(input));
for (int i = 0; i < dataPairNr; i++) {
structInput[i] = new int24(reader.ReadByte(), reader.ReadByte(), reader.ReadByte());
}
return structInput;
}
I feel really bad about the code.
Questions are:
What can I do to improve the function byteArrayToStructureArrayB?
As you can see in the int24 struct, I have a function called getInt32(). This function is only for bit shift operation of the struct. Is there a more efficient way?

Something like this should work:
public struct int24 {
public int24(byte[] array, int index) {
// TODO: choose what to do if out of bounds
a = array[index];
b = array[index + 1];
c = array[index + 2];
}
...
}
public static int24[] byteArrayToStructureArrayB(byte[] input) {
var count = input.Length / 3;
var result = new int24[count];
for (int i = 0; i < count; i++)
result[i] = new int24(input, i * 3);
return result;
}

Related

How to convert 16Bit byte array to audio clip data correctly?

I work with Media Foundataion and what I need to do is convert sound sample frame from byte to audio float data. In order to do it I use such method (that I found somewhere at google):
private static float[] Convert16BitByteArrayToAudioClipData(byte[] source, int headerOffset, int dataSize)
{
int wavSize = BitConverter.ToInt32(source, headerOffset);
headerOffset += sizeof(int);
Debug.AssertFormat(wavSize > 0 && wavSize == dataSize, "Failed to get valid 16-bit wav size: {0} from data bytes: {1} at offset: {2}", wavSize, dataSize, headerOffset);
int x = sizeof(Int16); // block size = 2
int convertedSize = wavSize / x;
float[] data = new float[convertedSize];
Int16 maxValue = Int16.MaxValue;
int i = 0;
while (i < convertedSize)
{
int offset = i * x + headerOffset;
data[i] = (float)BitConverter.ToInt16(source, offset) / maxValue;
++i;
}
Debug.AssertFormat(data.Length == convertedSize, "AudioClip .wav data is wrong size: {0} == {1}", data.Length, convertedSize);
return data;
}
I use it like this :
...
byte[] source = ...; // lenght 43776
... = Convert16BitByteArrayToAudioClipData(source , 0, 0);
...
Looks like this method works wrong, because if I pass an array with size 43776 as a result in while loop at index i = 21886 offset value will be offset = 43776 it lead to exception at this next method
data[i] = (float)BitConverter.ToInt16(source /*43776*/, offset /*43776*/) / maxValue;
because this values could not be the same.
Question is - how to fix this method? Or maybe someone can advice what to use instead?
EDIT
private static float[] Convert16BitByteArrayToAudioClipData(byte[] source)
{
float[] data = new float[source.Length];
for (int i = 0; i < source.Length; i++)
{
data[i] = (float) source[i];
}
return data;
}
Integers need to become -1..+1 floating point values
private static float[] Convert16BitByteArrayToAudioClipData(byte[] source)
{
float[] data = new float[source.Length];
for (int i = 0; i < source.Length; i++)
{
data[i] = ((float) source[i] / Int16.MaxValue); // <<---
}
return data;
}
Eventually I did it this way:
public static float[] Convert16BitByteArrayToAudioClipData(byte[] source)
{
int x = sizeof(Int16);
int convertedSize = source.Length / x;
float[] data = new float[convertedSize];
Int16 maxValue = Int16.MaxValue;
for (int i = 0; i < convertedSize; i++)
{
int offset = i * x;
data[i] = (float)BitConverter.ToInt16(source, offset) / maxValue;
++i;
}
return data;
}

C# - Vsprintf equivilant?Converting Char to Int

Using vsprintf, the c code below converts a char array to an int. How would I do this in c#? I have tried casting the c# string to an int, and then adding the values, but the return result is not the same. My c# code needs to return the same value as the c code does(3224115)
C# Code
var astring = "123";
int output = 0;
foreach(char c in astring){
var currentChar = (int)c;
output += c;
}
//output = 150
C Code
void vout(char *string, char *fmt, ...);
char fmt1 [] = "%d";
int main(void)
{
char string[32];
vout(string, fmt1, '123'); //output is 3224115
printf("The string is: %s\n", string);
}
void vout(char *string, char *fmt, ...)
{
va_list arg_ptr;
va_start(arg_ptr, fmt);
vsprintf(string, fmt, arg_ptr);
va_end(arg_ptr);
}
Finally figured out. Could be a bit cleaner, but it works, and gets the same output as the c code.
public static ulong getAsciiLiteral(string x)
{
int len = x.Length;
string[] strArray = new string[32];
byte[] finalByte = new byte[32];
int i = 0;
int i2 = 0;
int i3 = 0;
int offset = 0;
var hexFinalString = "0x";
var bytes = Encoding.ASCII.GetBytes(x);
if(len >= 5)
{
while (true)
{
if (4 + i3 == len)
{
offset = i3;
break;
}
else
{
i3++;
}
}
}
foreach (byte b in bytes)
{
strArray[i] = b.ToString("X2");
i++;
}
i = 0;
i3 = 0;
while (i3 < len - 1)
{
hexFinalString += strArray[offset];
offset++;
i3++;
}
var ret = Convert.ToUInt64(hexFinalString, 16);
return ret;
}

Function Anagram

An anagram is a word formed from another by rearranging its letters, using all the original letters exactly once; for example, orchestra can be rearranged into carthorse.
I want to write a function to return all anagrams of a given word (including the word itself) in any order.
For example GetAllAnagrams("abba") should return a collection containing "aabb", "abab", "abba", "baab", "baba", "bbaa".
Any help would be appreciated.
Here is a working function, making use of a GetPermutations() extension found elsewhere on stack overflow
public static List<string> GetAnagrams(string word)
{
HashSet<string> anagrams = new HashSet<string>();
char[] characters = word.ToCharArray();
foreach (IEnumerable<char> permutation in characters.GetPermutations())
{
anagrams.Add(new String(permutation.ToArray()));
}
return anagrams.OrderBy(x => x).ToList();
}
Here is the GetPermutations() extension and it's other necessary extensions:
public static IEnumerable<IEnumerable<T>> GetPermutations<T>(this IEnumerable<T> enumerable)
{
var array = enumerable as T[] ?? enumerable.ToArray();
var factorials = Enumerable.Range(0, array.Length + 1)
.Select(Factorial)
.ToArray();
for (var i = 0L; i < factorials[array.Length]; i++)
{
var sequence = GenerateSequence(i, array.Length - 1, factorials);
yield return GeneratePermutation(array, sequence);
}
}
private static IEnumerable<T> GeneratePermutation<T>(T[] array, IReadOnlyList<int> sequence)
{
var clone = (T[])array.Clone();
for (int i = 0; i < clone.Length - 1; i++)
{
Swap(ref clone[i], ref clone[i + sequence[i]]);
}
return clone;
}
private static int[] GenerateSequence(long number, int size, IReadOnlyList<long> factorials)
{
var sequence = new int[size];
for (var j = 0; j < sequence.Length; j++)
{
var facto = factorials[sequence.Length - j];
sequence[j] = (int)(number / facto);
number = (int)(number % facto);
}
return sequence;
}
static void Swap<T>(ref T a, ref T b)
{
T temp = a;
a = b;
b = temp;
}
private static long Factorial(int n)
{
long result = n;
for (int i = 1; i < n; i++)
{
result = result * i;
}
return result;
}
}
Here is a screenshot of the result:
And, finally, a github repository of the complete Visual Studio solution: Github
import java.util.Scanner;
import java.lang.String;
public class KrishaAnagram
{
public static void main(String[] args) {
Scanner Scan = new Scanner(System.in);
String s1, s2;
int sum1, sum2;
sum1 = sum2 = 0;
System.out.print("Enter fisrt string: ");
s1 = Scan.next();
System.out.print("Enter Second string: ");
s2 = Scan.next();
if (s1.length() != s2.length()) {
System.out.println("NOT ANAGRAM");
} else {
for (int i = 0; i < s1.length(); i++) {
char ch1 = s1.charAt(i);
char ch2 = s2.charAt(i);
sum1 += (int) ch1;
sum2 += (int) ch2;
}
if (sum1 == sum2)
System.out.println("IT IS AN ANAGRAM : s1 = " + sum1 + "s1 = " + sum2);
else
System.out.println("IT IS NOT AN ANAGRAM : s1 = " + sum1 + "s1 = " + sum2);;
}
}
}
//This is My way of solving anagram in java,Hope it helps.

Merging multiple Arrays with reference

I want to be able to have multiple arrays and be able to merge them together. This concept is easy, but I also want to be able to change one of the original arrays and have the merged array change as well. The idea is that some sort of reference system would be built effectively making the merged array an array of pointers.
Example Code:
int[] a1 = new int[5];
int[] a2 = new int[5];
for (int i = 0; i < 5; i++)
{
a1[i] = i;
a2[i] = i + 5;
}
int[] a3;
a3 = MergeFunction(a1, a2)
Console.WriteLine(a3[0] + "");
a1[0] = 10;
Console.WriteLine(a3[0] + "");
Console.ReadKey();
This would output first 0, then 10
you can use Linq to solve this. For example
void Main()
{
int[] a1 = new int[5];
int[] a2 = new int[5];
for (int i = 0; i < 5; i++)
{
a1[i] = i;
a2[i] = i + 5;
}
IEnumerable<int> a3;
a3 = MergeFunction(a1, a2);
Console.WriteLine(a3.ToArray()[0] + "");
a1[0] = 10;
Console.WriteLine(a3.ToArray()[0] + "");
Console.ReadKey();
}
public IEnumerable<int> MergeFunction(int[] a1, int[] a2)
{
return a1.Union(a2);
}
Because of the deferred execution of linq it shows also the changes in the base arrays.
With this in mind you can write a small class to make the syntax for item access similar to the array syntax for item access. For example:
void Main()
{
int[] a1 = new int[5];
int[] a2 = new int[5];
for (int i = 0; i < 5; i++)
{
a1[i] = i;
a2[i] = i + 5;
}
ArrayMerger<int> a3 = new ArrayMerger<int>(a1,a2);
Console.WriteLine(a3[0] + "");
a1[0] = 10;
Console.WriteLine(a3[0] + "");
a2[0] = 15;
Console.WriteLine(a3[5] + "");
}
public class ArrayMerger<T>
{
private readonly IEnumerable<T> arrayUnion;
public ArrayMerger(T[] array1, T[] array2)
{
arrayUnion = array1.Union(array2);
}
public T this[int i]
{
get
{
return arrayUnion.ElementAt(i);
}
}
}
I think there's no reference system you are looking for. You have to do the merging everytime when there's a change made to the original array.
In my case, I didn't actually want to use ints but another class that I had made so for the sample code, I will be using an arbitrary Class, but if someone else wants to use an int, go to this page and look at solutions for value variables.
C#: Array of references / pointers to a number of integers
Firstly, I made a very simple variable class
public class Variable
{
public int a;
public int b;
public int c;
public Variable(int a, int b, int c)
{
this.a = a;
this.b = b;
this.c = c;
}
}
Finally, here is the code to test the reference idea
static void Main(string[] args)
{
//definition of variables
Variable[] a1 = new Variable[5];
Variable[] a2 = new Variable[5];
//fill the variables
for (int i = 0; i < 5; i++)
{
a1[i] = new Variable(i, i* 2, i*3);
a2[i] = new Variable(i + 5, (i+ 5) * 2, (i+5) * 3);
}
//define combination
Variable[] a3;
//join arrays
a3 = a1.Union(a2).ToArray();
//inefficient print
Console.WriteLine(a3[0].a + "");
//change original array
a1[0].a = 10;
//inefficient print
Console.WriteLine(a3[0].a + "");
Console.ReadKey();
}
This outputs 0 then 10

how can i find lcs length between two large strings

I've written the following code in C# for obtaining the length of longest common subsequence of two texts given by use, but it doesn't work with large strings. Could you please help me. I'm really confused.
public Form1()
{
InitializeComponent();
}
public int lcs(char[] s1, char[] s2, int s1size, int s2size)
{
if (s1size == 0 || s2size == 0)
{
return 0;
}
else
{
if (s1[s1size - 1] == s2[s2size - 1])
{
return (lcs(s1, s2, s1size - 1, s2size - 1) + 1);
}
else
{
int x = lcs(s1, s2, s1size, s2size - 1);
int y = lcs(s1, s2, s1size - 1, s2size);
if (x > y)
{
return x;
}
else
return y;
}
}
}
private void button1_Click(object sender, EventArgs e)
{
string st1 = textBox2.Text.Trim(' ');
string st2 = textBox3.Text.Trim(' ');
char[] a = st1.ToCharArray();
char[] b = st2.ToCharArray();
int s1 = a.Length;
int s2 = b.Length;
textBox1.Text = lcs(a, b, s1, s2).ToString();
}
Here you are using the Recursion method. So it leads the program to occur performance problems as you mentioned.
Instead of recursion, use the dynamic programming approach.
Here is the C# Code.
public static void LCS(char[] str1, char[] str2)
{
int[,] l = new int[str1.Length, str2.Length];
int lcs = -1;
string substr = string.Empty;
int end = -1;
for (int i = 0; i < str1.Length; i++)
{
for (int j = 0; j < str2.Length; j++)
{
if (str1[i] == str2[j])
{
if (i == 0 || j == 0)
{
l[i, j] = 1;
}
else
l[i, j] = l[i - 1, j - 1] + 1;
if (l[i, j] > lcs)
{
lcs = l[i, j];
end = i;
}
}
else
l[i, j] = 0;
}
}
for (int i = end - lcs + 1; i <= end; i++)
{
substr += str1[i];
}
Console.WriteLine("Longest Common SubString Length = {0}, Longest Common Substring = {1}", lcs, substr);
}
Here is a solution how to find the longest common substring in C#:
public static string GetLongestCommonSubstring(params string[] strings)
{
var commonSubstrings = new HashSet<string>(strings[0].GetSubstrings());
foreach (string str in strings.Skip(1))
{
commonSubstrings.IntersectWith(str.GetSubstrings());
if (commonSubstrings.Count == 0)
return string.Empty;
}
return commonSubstrings.OrderByDescending(s => s.Length).DefaultIfEmpty(string.Empty).First();
}
private static IEnumerable<string> GetSubstrings(this string str)
{
for (int c = 0; c < str.Length - 1; c++)
{
for (int cc = 1; c + cc <= str.Length; cc++)
{
yield return str.Substring(c, cc);
}
}
}
I found it here: http://www.snippetsource.net/Snippet/75/longest-common-substring
Just for fun, here is one example using Queue<T>:
string LongestCommonSubstring(params string[] strings)
{
return LongestCommonSubstring(strings[0], new Queue<string>(strings.Skip(1)));
}
string LongestCommonSubstring(string x, Queue<string> strings)
{
if (!strings.TryDequeue(out var y))
{
return x;
}
var output = string.Empty;
for (int i = 0; i < x.Length; i++)
{
for (int j = x.Length - i; j > -1; j--)
{
string common = x.Substring(i, j);
if (y.IndexOf(common) > -1 && common.Length > output.Length) output = common;
}
}
return LongestCommonSubstring(output, strings);
}
It's still using recursion though, but it's a nice example of Queue<T>.
I refactored the C++ code from Ashutosh Singh at https://iq.opengenus.org/longest-common-substring-using-rolling-hash/ to create a rolling hash approach in C# - this will find the substring in O(N * log(N)^2) time and O(N) space
using System;
using System.Collections.Generic;
public class RollingHash
{
private class RollingHashPowers
{
// _mod = prime modulus of polynomial hashing
// any prime number over a billion should suffice
internal const int _mod = (int)1e9 + 123;
// _hashBase = base (point of hashing)
// this should be a prime number larger than the number of characters used
// in my use case I am only interested in ASCII (256) characters
// for strings in languages using non-latin characters, this should be much larger
internal const long _hashBase = 257;
// _pow1 = powers of base modulo mod
internal readonly List<int> _pow1 = new List<int> { 1 };
// _pow2 = powers of base modulo 2^64
internal readonly List<long> _pow2 = new List<long> { 1L };
internal void EnsureLength(int length)
{
if (_pow1.Capacity < length)
{
_pow1.Capacity = _pow2.Capacity = length;
}
for (int currentIndx = _pow1.Count - 1; currentIndx < length; ++currentIndx)
{
_pow1.Add((int)(_pow1[currentIndx] * _hashBase % _mod));
_pow2.Add(_pow2[currentIndx] * _hashBase);
}
}
}
private class RollingHashedString
{
readonly RollingHashPowers _pows;
readonly int[] _pref1; // Hash on prefix modulo mod
readonly long[] _pref2; // Hash on prefix modulo 2^64
// Constructor from string:
internal RollingHashedString(RollingHashPowers pows, string s, bool caseInsensitive = false)
{
_pows = pows;
_pref1 = new int[s.Length + 1];
_pref2 = new long[s.Length + 1];
const long capAVal = 'A';
const long capZVal = 'Z';
const long aADif = 'a' - 'A';
unsafe
{
fixed (char* c = s)
{
// Fill arrays with polynomial hashes on prefix
for (int i = 0; i < s.Length; ++i)
{
long v = c[i];
if (caseInsensitive && capAVal <= v && v <= capZVal)
{
v += aADif;
}
_pref1[i + 1] = (int)((_pref1[i] + v * _pows._pow1[i]) % RollingHashPowers._mod);
_pref2[i + 1] = _pref2[i] + v * _pows._pow2[i];
}
}
}
}
// Rollingnomial hash of subsequence [pos, pos+len)
// If mxPow != 0, value automatically multiply on base in needed power.
// Finally base ^ mxPow
internal Tuple<int, long> Apply(int pos, int len, int mxPow = 0)
{
int hash1 = _pref1[pos + len] - _pref1[pos];
long hash2 = _pref2[pos + len] - _pref2[pos];
if (hash1 < 0)
{
hash1 += RollingHashPowers._mod;
}
if (mxPow != 0)
{
hash1 = (int)((long)hash1 * _pows._pow1[mxPow - (pos + len - 1)] % RollingHashPowers._mod);
hash2 *= _pows._pow2[mxPow - (pos + len - 1)];
}
return Tuple.Create(hash1, hash2);
}
}
private readonly RollingHashPowers _rhp;
public RollingHash(int longestLength = 0)
{
_rhp = new RollingHashPowers();
if (longestLength > 0)
{
_rhp.EnsureLength(longestLength);
}
}
public string FindCommonSubstring(string a, string b, bool caseInsensitive = false)
{
// Calculate max neede power of base:
int mxPow = Math.Max(a.Length, b.Length);
_rhp.EnsureLength(mxPow);
// Create hashing objects from strings:
RollingHashedString hash_a = new RollingHashedString(_rhp, a, caseInsensitive);
RollingHashedString hash_b = new RollingHashedString(_rhp, b, caseInsensitive);
// Binary search by length of same subsequence:
int pos = -1;
int low = 0;
int minLen = Math.Min(a.Length, b.Length);
int high = minLen + 1;
var tupleCompare = Comparer<Tuple<int, long>>.Default;
while (high - low > 1)
{
int mid = (low + high) / 2;
List<Tuple<int, long>> hashes = new List<Tuple<int, long>>(a.Length - mid + 1);
for (int i = 0; i + mid <= a.Length; ++i)
{
hashes.Add(hash_a.Apply(i, mid, mxPow));
}
hashes.Sort(tupleCompare);
int p = -1;
for (int i = 0; i + mid <= b.Length; ++i)
{
if (hashes.BinarySearch(hash_b.Apply(i, mid, mxPow), tupleCompare) >= 0)
{
p = i;
break;
}
}
if (p >= 0)
{
low = mid;
pos = p;
}
else
{
high = mid;
}
}
// Output answer:
return pos >= 0
? b.Substring(pos, low)
: string.Empty;
}
}

Categories