Swig and C#: cannot assign value to struct array member - c#

The C++ struct has one fixed 2d char array as member
typedef struct ReqSubscribeField
{
char routing_key[100][56];
}ReqSubscribeField_t;
and I used Swig to generate the following C# class representing the struct
public class ReqSubscribeField_t : global::System.IDisposable {
private global::System.Runtime.InteropServices.HandleRef swigCPtr;
protected bool swigCMemOwn;
...
public SWIGTYPE_p_a_56__char routing_key {
set {
libnhmdapiPINVOKE.ReqSubscribeField_t_routing_key_set(swigCPtr, SWIGTYPE_p_a_56__char.getCPtr(value));
}
get {
global::System.IntPtr cPtr = libnhmdapiPINVOKE.ReqSubscribeField_t_routing_key_get(swigCPtr);
SWIGTYPE_p_a_56__char ret = (cPtr == global::System.IntPtr.Zero) ? null : new SWIGTYPE_p_a_56__char(cPtr, false);
return ret;
}
}
public ReqSubscribeField_t() : this(libnhmdapiPINVOKE.new_ReqSubscribeField_t(), true) {
}
}
and the following swig type representing the fixed size char array
public class SWIGTYPE_p_a_56__char {
private global::System.Runtime.InteropServices.HandleRef swigCPtr;
public SWIGTYPE_p_a_56__char(global::System.IntPtr cPtr, bool futureUse) {
swigCPtr = new global::System.Runtime.InteropServices.HandleRef(this, cPtr);
}
protected SWIGTYPE_p_a_56__char() {
swigCPtr = new global::System.Runtime.InteropServices.HandleRef(null, global::System.IntPtr.Zero);
}
internal static global::System.Runtime.InteropServices.HandleRef getCPtr(SWIGTYPE_p_a_56__char obj) {
return (obj == null) ? new global::System.Runtime.InteropServices.HandleRef(null, global::System.IntPtr.Zero) : obj.swigCPtr;
}
}
and I want to assign values to routing_key member and use a parameter of a function.
I tried to assign values to **routing_key ** with following code:
IntPtr[] ptrs = new IntPtr[100];
string inst = "abcd".PadRight(56, '\0');
Console.WriteLine(inst.Length);
ptrs[0] = Marshal.StringToHGlobalAnsi(inst);
for (int i = 1; i < 100; i++)
{
ptrs[i] = Marshal.StringToHGlobalAnsi(string.Empty.PadRight(56, '\0'));
}
GCHandle gch = GCHandle.Alloc(ptrs, GCHandleType.Pinned);
IntPtr inputs = gch.AddrOfPinnedObject();
ReqSubscribeField_t subscribeField_T = new ReqSubscribeField_t();
SWIGTYPE_p_a_56__char swigInstruments = new SWIGTYPE_p_a_56__char(inputs, true);
subscribeField_T.routing_key = swigInstruments;
or
char[,] routeKeys = new char[100, 56];
routeKeys[0, 0] = 'a';
routeKeys[0, 1] = 'b';
routeKeys[0, 2] = 'c';
routeKeys[0, 3] = 'd';
routeKeys[0, 4] = '\0';
GCHandle gch = GCHandle.Alloc(routeKeys, GCHandleType.Pinned);
IntPtr inputs = gch.AddrOfPinnedObject();
ReqSubscribeField_t subscribeField_T = new ReqSubscribeField_t();
SWIGTYPE_p_a_56__char swigInstruments = new SWIGTYPE_p_a_56__char(inputs, true);
subscribeField_T.routing_key = swigInstruments;
Neither worked, the C# setter did not work, there is no data in the variable. Please help!!!

Found a solution, I just need to create a helper function
void DisplayDataHelper(char *data[], int cnt)
{
ReqSubscribeField_t request = {0};
for (int i = 0; i < cnt && i < 100; i++) {
for (int j = 0; j < 56; j++) {
if (data[i][j] == '\0') {
for (int k = j; k < 10; k++) {
request.routing_key[i][k] = '\0';
}
break;
}
request.routing_key[i][j] = data[i][j];
}
}
this->DisplayData(request);
};
and in C#, use
List<string> instruments = new List<string>() { "abc", "def", "ghi" };
IntPtr[] ptrs = new IntPtr[instruments.Count];
for (int i = 0; i < instruments.Count; i++)
{
ptrs[i] = Marshal.StringToHGlobalAnsi(instruments[i]);
}
GCHandle gch = GCHandle.Alloc(ptrs, GCHandleType.Pinned);
IntPtr inputs = gch.AddrOfPinnedObject();
SWIGTYPE_p_p_char swigInstruments = new SWIGTYPE_p_p_char(inputs, true);
myTest.DisplayDataHelper(swigInstruments, 3);
then it works, seems like swig typemap has some bug with fixed length array.

Related

Make a password generator

I am currently trying to make a random password generator.
My code works fine if I only pick one type of symbols.
What's the best way to make my code to word for more than one type?
Also what parameters would you add to make the password more secured?
I am thinking of adding an if loop to check if there are more than two same letters, symbols or numbers in a row.
That's how my interface looks like:
and that is my code:
public partial class Form1 : Form
{
// Max number of identical characters in a row
const int Maximum_Identical = 2;
// lower case chars
const string lower_chars = "abcdefghijklmnopqrstuvwxyz";
// capital chars
const string capital_chars = "ABCDEFGHIJKLMNOPQRSTUVWXYZ";
// numbers
const string numbers = "0123456789";
// symbols
const string symbols = #"!#$%&*#\";
// password lenght
int lenght;
private void button1_Click(object sender, EventArgs e)
{
//use stringbuilder so I can add more chars later
StringBuilder password = new StringBuilder();
//take max lenght from numericUpDown
lenght = Convert.ToInt32(numericUpDown1.Value);
// random instance so I can use Next and don't get loops
Random rdm = new Random();
if (small_letters__Box.Checked)
{
//add a random small character to pass untill it reaches the selected lenght
while (lenght-- > 0 )
{
password.Append(lower_chars[rdm.Next(lower_chars.Length)]);
}
}
if (capital_letters__Box.Checked)
{
//add a random capital character to pass untill it reaches the selected lenght
while (lenght-- > 0)
{
password.Append(capital_chars[rdm.Next(capital_chars.Length)]);
}
}
if (numbers_Box.Checked)
{
//add a random character to pass untill it reaches the selected lenght
while (lenght-- > 0)
{
password.Append(numbers[rdm.Next(numbers.Length)]);
}
}
if (symbols_Box.Checked)
{
//add a random character to pass untill it reaches the selected lenght
while (lenght-- > 0)
{
password.Append(symbols[rdm.Next(symbols.Length)]);
}
}
textBox1.Text = password.ToString();
}
private void numericUpDown1_ValueChanged(object sender, EventArgs e)
{
}
}
Your password generation has 2 steps.
Determine the character set
Create a password randomly from the character set of length n
Function 1 creates the character set:
// Make sure you have using System.Linq;
private List<char> GetCharacterSet()
{
IEnumerable<char> returnSet = new char[]{};
if (small_letters__Box.Checked)
{
returnSet = returnSet.Append(lower_chars);
}
if (capital_letters__Box.Checked)
{
returnSet = returnSet.Append(capital_chars);
}
if (numbers_Box.Checked)
{
returnSet = returnSet.Append(numbers);
}
if (symbols_Box.Checked)
{
returnSet = returnSet.Append(symbols);
}
return returnSet.ToList();
}
Function 2 creates a password of given length from your character set
private string GetPassword(int length, List<char> characterSet)
{
if(characterSet.Count < 1)
{
throw new ArgumentException("characterSet contains no items!");
}
if(length < 1)
{
return "";
}
Random rdm = new Random();
StringBuilder password = new StringBuilder();
for(int i = 0; i < length; i++){
int charIndex = rdm.Next(0, characterSet.Count)
password.Append(characterSet[charIndex]);
}
return password.ToString();
}
Then simply rig your button click event handler to call these functions and display the resulting password.
below code is my already written code which I wrote more than a couple of years ago and I still use it in my many of my projects where needed, it covers all you are in need of
using System;
using System.Collections.Generic;
using System.Diagnostics.Contracts;
using System.Linq;
using System.Text;
using System.Threading;
public static class ArrayExtentions
{
public static object[] Shuffle(this object[] array)
{
var alreadySwaped = new HashSet<Tuple<int, int>>();
var rndLoopCount = RandomUtils.GetRandom(Convert.ToInt32(array.Length / 4), Convert.ToInt32((array.Length / 2) + 1));
for (var i = 0; i <= rndLoopCount; i++)
{
int rndIndex1 = 0, rndIndex2 = 0;
do
{
rndIndex1 = RandomUtils.GetRandom(0, array.Length);
rndIndex2 = RandomUtils.GetRandom(0, array.Length);
} while (alreadySwaped.Contains(new Tuple<int, int>(rndIndex1, rndIndex2)));
alreadySwaped.Add(new Tuple<int, int>(rndIndex1, rndIndex2));
var swappingItem = array[rndIndex1];
array[rndIndex1] = array[rndIndex2];
array[rndIndex2] = swappingItem;
}
return array;
}
}
public class RandomUtils
{
private static readonly ThreadLocal<Random> RndLocal = new ThreadLocal<Random>(() => new Random(GetUniqueSeed()));
private static int GetUniqueSeed()
{
long next, current;
var guid = Guid.NewGuid().ToByteArray();
var seed = BitConverter.ToInt64(guid, 0);
do
{
current = Interlocked.Read(ref seed);
next = current * BitConverter.ToInt64(guid, 3);
} while (Interlocked.CompareExchange(ref seed, next, current) != current);
return (int)next ^ Environment.TickCount;
}
public static int GetRandom(int min, int max)
{
Contract.Assert(max >= min);
return RndLocal.Value.Next(min, max);
}
public static int GetRandom(int max)
{
return RndLocal.Value.Next(max);
}
public static double GetRandom()
{
return RndLocal.Value.NextDouble();
}
}
public class StringUtility
{
private const string UpperAlpha = "ABCDEFGHIJKLMNOPQRSTUWXYZ";
private const string LowerAlpha = "abcdefghijklmnopqrstuwxyz";
private const string Numbers = "0123456789";
private const string SpecialChars = "~!##$%^&*()_-+=.?";
private static string CreateSourceString(bool includeLowerCase, bool includeUpperCase, bool includenumbers, bool includeSpChars)
{
Contract.Assert(includeLowerCase || includeUpperCase || includenumbers || includeSpChars);
var sb = new StringBuilder();
if (includeLowerCase) sb.Append(LowerAlpha);
if (includeUpperCase) sb.Append(UpperAlpha);
if (includenumbers) sb.Append(Numbers);
if (includeSpChars) sb.Append(SpecialChars);
return sb.ToString();
}
private static string GenerateString(string sourceString, int length = 6)
{
var rndString = Shuffle(sourceString);
var builder = new StringBuilder();
for (var i = 0; i < length; i++)
builder.Append(rndString[RandomUtils.GetRandom(0, rndString.Length)]);
return builder.ToString();
}
public static string GenerateRandomString(int length = 6,
bool includenumbers = false,
bool includeSpChars = false)
{
var sourceStr = CreateSourceString(true, true, includenumbers, includeSpChars);
return GenerateString(sourceStr, length);
}
public static string GenerateRandomString(int minLength,
int maxLength,
bool includenumbers = false,
bool includeSpChars = false)
{
if (maxLength < minLength) maxLength = minLength;
var len = RandomUtils.GetRandom(minLength, maxLength + 1);
return GenerateRandomString(len, includenumbers, includeSpChars);
}
public static string Shuffle(string str)
{
var alreadySwaped = new HashSet<Tuple<int, int>>();
var rndLoopCount = RandomUtils.GetRandom(Convert.ToInt32(str.Length / 4), Convert.ToInt32((str.Length / 2) + 1));
var strArray = str.ToArray();
for (var i = 0; i <= rndLoopCount; i++)
{
int rndIndex1 = 0, rndIndex2 = 0;
do
{
rndIndex1 = RandomUtils.GetRandom(0, str.Length);
rndIndex2 = RandomUtils.GetRandom(0, str.Length);
} while (alreadySwaped.Contains(new Tuple<int, int>(rndIndex1, rndIndex2)));
alreadySwaped.Add(new Tuple<int, int>(rndIndex1, rndIndex2));
var swappingChar = strArray[rndIndex1];
strArray[rndIndex1] = strArray[rndIndex2];
strArray[rndIndex2] = swappingChar;
}
return new string(strArray);
}
public static string GeneratePassword(PasswordComplexity complexityLevel)
{
switch (complexityLevel)
{
case PasswordComplexity.Simple: return GenerateSimplePassword();
case PasswordComplexity.Medium: return GenerateMediumPassword();
case PasswordComplexity.Strong: return GenerateStrongPassword();
case PasswordComplexity.Stronger: return GenerateStrongerPassword();
}
return null;
}
private static string GenerateSimplePassword()
{
return GenerateRandomString(6, 9);
}
private static string GenerateMediumPassword()
{
var passLen = RandomUtils.GetRandom(6, 10);
var numCount = RandomUtils.GetRandom(1, 3);
var alphaStr = GenerateRandomString(passLen - numCount);
var numStr = GenerateString(Numbers, numCount);
var pass = alphaStr + numStr;
return Shuffle(pass);
}
private static string GenerateStrongPassword()
{
var lowerCharCount = RandomUtils.GetRandom(2, 5);
var upperCharCount = RandomUtils.GetRandom(2, 5);
var numCount = RandomUtils.GetRandom(2, 4);
var spCharCount = RandomUtils.GetRandom(2, 4);
var lowerAlphaStr = GenerateString(LowerAlpha, lowerCharCount);
var upperAlphaStr = GenerateString(UpperAlpha, upperCharCount);
var spCharStr = GenerateString(SpecialChars, spCharCount);
var numStr = GenerateString(Numbers, numCount);
var pass = lowerAlphaStr + upperAlphaStr + spCharStr + numStr;
return Shuffle(pass);
}
private static string GenerateStrongerPassword()
{
var lowerCharCount = RandomUtils.GetRandom(5, 12);
var upperCharCount = RandomUtils.GetRandom(4, 8);
var numCount = RandomUtils.GetRandom(4, 6);
var spCharCount = RandomUtils.GetRandom(4, 6);
var lowerAlphaStr = GenerateString(LowerAlpha, lowerCharCount);
var upperAlphaStr = GenerateString(UpperAlpha, upperCharCount);
var spCharStr = GenerateString(SpecialChars, spCharCount);
var numStr = GenerateString(Numbers, numCount);
var pass = lowerAlphaStr + upperAlphaStr + spCharStr + numStr;
return Shuffle(Shuffle(pass));
}
public enum PasswordComplexity
{
Simple, Medium, Strong, Stronger
}
}
I write this code for you. You can just copy and use it. All of my code is just a method that you can pass appropriate arguments and it gives you back a completely randomized password. I test it several times before answering your question, It works well.
private string GeneratePassword(bool useCapitalLetters, bool useSmallLetters, bool useNumbers, bool useSymbols, int passLenght)
{
Random random = new Random();
StringBuilder password = new StringBuilder(string.Empty);
//This for loop is for selecting password chars in order
for (int i = 0;;)
{
if (useCapitalLetters)
{
password.Append((char)random.Next(65, 91)); //Capital letters
++i; if (i >= passLenght) break;
}
if (useSmallLetters)
{
password.Append((char)random.Next(97, 122)); //Small letters
++i; if (i >= passLenght) break;
}
if (useNumbers)
{
password.Append((char)random.Next(48, 57)); //Number letters
++i; if (i >= passLenght) break;
}
if (useSymbols)
{
password.Append((char)random.Next(35, 38)); //Symbol letters
++i; if (i >= passLenght) break;
}
}
//This for loop is for disordering password characters
for (int i = 0; i < password.Length; ++i)
{
int randomIndex1 = random.Next(password.Length);
int randomIndex2 = random.Next(password.Length);
char temp = password[randomIndex1];
password[randomIndex1] = password[randomIndex2];
password[randomIndex2] = temp;
}
return password.ToString();
}
an answer with complete randomize char and using the max repeat of char, i have added a shuffle string function:
const int Maximum_Identical = 2; // Max number of identical characters in a row
const string lower_chars = "abcdefghijklmnopqrstuvwxyz"; // lower case chars
const string capital_chars = "ABCDEFGHIJKLMNOPQRSTUVWXYZ"; //capital chars
const string numbers = "0123456789"; //numbers
const string symbols = #"!#$%&*#\"; //symbols
int lenght = 6; //
bool lowercase = true, capital=true, num=true, sym=true;
List<char[]> PasswordSet = new List<char[]>();
List<char[]> charSet = new List<char[]>();
List<int[]> countSet = new List<int[]>();
if (lowercase) charSet.Add(lower_chars.ToArray());
if (capital) charSet.Add(capital_chars.ToArray());
if (num) charSet.Add(numbers.ToArray());
if (sym) charSet.Add(symbols.ToArray());
foreach(var c in charSet)
countSet.Add(new int[c.Length]);
Random rdm = new Random();
//we create alist with each type with a length char (max repeat char included)
for(int i = 0; i < charSet.Count;i++)
{
var lng = 1;
var p0 = "";
while (true)
{
var ind = rdm.Next(0, charSet[i].Length);
if (countSet[i][ind] < Maximum_Identical )
{
countSet[i][ind] += 1;
lng++;
p0 += charSet[i][ind];
}
if (lng == lenght) break;
}
PasswordSet.Add(p0.ToArray());
}
//generate a password with the desired length with at less one char in desired type,
//and we choose randomly in desired type to complete the length of password
var password = "";
for(int i = 0; i < lenght; i++)
{
char p;
if (i < PasswordSet.Count)
{
int id;
do
{
id = rdm.Next(0, PasswordSet[i].Length);
p = PasswordSet[i][id];
} while (p == '\0');
password += p;
PasswordSet[i][id] = '\0';
}
else
{
int id0;
int id1;
do
{
id0 = rdm.Next(0, PasswordSet.Count);
id1 = rdm.Next(0, PasswordSet[id0].Length);
p = PasswordSet[id0][id1];
} while (p == '\0');
password += p;
PasswordSet[id0][id1] = '\0';
}
}
//you could shuffle the final password
password = Shuffle.StringMixer(password);
shuffle string function:
static class Shuffle
{
static System.Random rnd = new System.Random();
static void Fisher_Yates(int[] array)
{
int arraysize = array.Length;
int random;
int temp;
for (int i = 0; i < arraysize; i++)
{
random = i + (int)(rnd.NextDouble() * (arraysize - i));
temp = array[random];
array[random] = array[i];
array[i] = temp;
}
}
public static string StringMixer(string s)
{
string output = "";
int arraysize = s.Length;
int[] randomArray = new int[arraysize];
for (int i = 0; i < arraysize; i++)
{
randomArray[i] = i;
}
Fisher_Yates(randomArray);
for (int i = 0; i < arraysize; i++)
{
output += s[randomArray[i]];
}
return output;
}
}
There you go :
string[] charList =
{
"abcdefghijklmnopqrstuvwxyz",
"ABCDEFGHIJKLMNOPQRSTUVWXYZ",
"0123456789",
"#\"!#$%&*#\\"
};
int desiredPasswordLength = 12;
var randomNumberGenerator = new Random();
string generatedPassword = "";
for (int i = randomNumberGenerator.Next() % 4; desiredPasswordLength > 0; i = (i+1) % 4)
{
var takeRandomChars = randomNumberGenerator.Next() % 3;
for (int j = 0; j < takeRandomChars; j++)
{
var randomChar = randomNumberGenerator.Next() % charList[i].Length;
char selectedChar = charList[i][randomChar % charList[i].Length];
generatedPassword = string.Join("", generatedPassword, selectedChar);
}
desiredPasswordLength -= takeRandomChars;
}
Console.WriteLine("Generated password: {0}",generatedPassword);
private static string GeneratorPassword(UInt16 length = 8)
{
const string chars = "0123456789abcdefghijklmnopqrstuvwxyzABCDEFGHIJKLMNOPQRSTUVWXYZ0";
System.Text.StringBuilder sb = new System.Text.StringBuilder();
Random rnd = new Random();
System.Threading.Thread.Sleep(2);
for (int i = 0; i < length; i++)
{
int index = 0;
if (i % 3 == 0)
{
index = rnd.Next(0, 10);
}
else if (i % 3 == 1)
{
index = rnd.Next(10, 36);
}
else
{
index = rnd.Next(36, 62);
}
sb.Insert(rnd.Next(0, sb.Length), chars[index].ToString());
}
return sb.ToString();
}
static void Main(string[] args)
{
for (int j= 0; j < 100; j++)
{
Console.WriteLine( GeneratorPassword());
}
Console.ReadLine();
}

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;
}

Array list is not being sorted properly when it contains string

I'm trying to sort a lists of alphanumeric values , in other words a list that contains numbers and strings
Example : BOB10, BOT20, ETC...
List<Object> myList = _items.OrderBy(x => x.FirstName).ToList();
_items= new List<Object>(myList);
But still the output is : BOT20 , BOB10
what is wrong?
First :
Try the alphanumeric algorithm approach ,
First implement the algorithm in a new class, than do this :
List<Object> yourList = new List < Object >(thePreviousList.OrderBy(x => x.FirstName, new AlphanumComparatorFast()).ToList())
As it was explained here :
http://www.dotnetperls.com/alphanumeric-sorting
Implement the algorithm AlphanumComparatorFast by creating a new class , than just call it
Edited :
The alpha algo below :
Public class AlphanumComparatorFast : IComparer
{
public int Compare(object x, object y)
{
string s1 = x as string;
if (s1 == null)
{
return 0;
}
string s2 = y as string;
if (s2 == null)
{
return 0;
}
int len1 = s1.Length;
int len2 = s2.Length;
int marker1 = 0;
int marker2 = 0;
// Walk through two the strings with two markers.
while (marker1 < len1 && marker2 < len2)
{
char ch1 = s1[marker1];
char ch2 = s2[marker2];
// Some buffers we can build up characters in for each chunk.
char[] space1 = new char[len1];
int loc1 = 0;
char[] space2 = new char[len2];
int loc2 = 0;
// Walk through all following characters that are digits or
// characters in BOTH strings starting at the appropriate marker.
// Collect char arrays.
do
{
space1[loc1++] = ch1;
marker1++;
if (marker1 < len1)
{
ch1 = s1[marker1];
}
else
{
break;
}
} while (char.IsDigit(ch1) == char.IsDigit(space1[0]));
do
{
space2[loc2++] = ch2;
marker2++;
if (marker2 < len2)
{
ch2 = s2[marker2];
}
else
{
break;
}
} while (char.IsDigit(ch2) == char.IsDigit(space2[0]));
// If we have collected numbers, compare them numerically.
// Otherwise, if we have strings, compare them alphabetically.
string str1 = new string(space1);
string str2 = new string(space2);
int result;
if (char.IsDigit(space1[0]) && char.IsDigit(space2[0]))
{
int thisNumericChunk = int.Parse(str1);
int thatNumericChunk = int.Parse(str2);
result = thisNumericChunk.CompareTo(thatNumericChunk);
}
else
{
result = str1.CompareTo(str2);
}
if (result != 0)
{
return result;
}
}
return len1 - len2;
}
}
Why not use List.Sort() instead of OrderBy?
using System;
using System.Collections.Generic;
namespace Test {
static class Program {
static void Main() {
List<string> list = new List<string>() {"BOT20", "BOB10", "BUG40", "BAG90"};
list.Sort();
foreach(var el in list) {
Console.Write(el + ">");
}
}
}
}
Outputs: BAG90>BOB10>BOT20>BUG40>

Splitting a word with dots between each char

I have a word, for example:
qwerty
I want to add a dot between each char, but also take into consideration all possible cases.
For example, output should be:
qwerty
qwert.y
qwer.ty
qwer.t.y
qwe.rty
qwe.rt.y
qwe.r.ty
qwe.r.t.y
qw.erty
qw.ert.y
qw.er.ty
qw.er.t.y
qw.e.rty
qw.e.rt.y
qw.e.r.ty
qw.e.r.t.y
q.werty
q.wert.y
q.wer.ty
q.wer.t.y
q.we.rty
q.we.rt.y
q.we.r.ty
q.we.r.t.y
q.w.erty
q.w.ert.y
q.w.er.ty
q.w.er.t.y
q.w.e.rty
q.w.e.rt.y
q.w.e.r.ty
q.w.e.r.t.y
I have so far this code:
private void button12_Click(object sender, EventArgs e)
{
int maxPossibilities = Convert.ToInt32(Math.Pow(2.0, txtInput.Text.Length));
List<string> allPossibilities = new List<string>();
for (int i = 0; i < maxPossibilities; i++)
{
string result = "";
string added = Convert.ToString(i, 2).PadLeft(txtInput.Text.Length - 1);
for (int j = 0; j < txtInput.Text.Length; j++)
{
result += txtInput.Text[j] + ((j < txtInput.Text.Length - 1) && (added[j].Equals('1')) ? "." : "");
}
allPossibilities.Add(result);
}
}
I am getting the following output:
qwerty
qwert.y
qwer.ty
qwer.t.y
qwe.rty
qwe.rt.y
qwe.r.ty
qwe.r.t.y
qw.erty
qw.ert.y
qw.er.ty
qw.er.t.y
qw.e.rty
qw.e.rt.y
qw.e.r.ty
qw.e.r.t.y
q.werty
q.wert.y
q.wer.ty
q.wer.t.y
q.we.rty
q.we.rt.y
q.we.r.ty
q.we.r.t.y
q.w.erty
q.w.ert.y
q.w.er.ty
q.w.er.t.y
q.w.e.rty
q.w.e.rt.y
q.w.e.r.ty
q.w.e.r.t.y
q.werty
q.werty
q.wert.y
q.wert.y
q.wer.ty
q.wer.ty
q.wer.t.y
q.wer.t.y
q.we.rty
q.we.rty
q.we.rt.y
q.we.rt.y
q.we.r.ty
q.we.r.ty
q.we.r.t.y
q.we.r.t.y
q.w.erty
q.w.erty
q.w.ert.y
q.w.ert.y
q.w.er.ty
q.w.er.ty
q.w.er.t.y
q.w.er.t.y
q.w.e.rty
q.w.e.rty
q.w.e.rt.y
q.w.e.rt.y
q.w.e.r.ty
q.w.e.r.ty
q.w.e.r.t.y
q.w.e.r.t.y
There are some duplicates in the output, but shouldn't be. Any help is appreciated.
Here is a slight variation on your algorithm that looks at the bits of i to determine which positions should get dots:
string input = "qwerty";
int maxPossibilities = Convert.ToInt32(Math.Pow(2.0, input.Length));
List<string> allPossibilities = new List<string>();
for(int i = 0; i < maxPossibilities; ++i)
{
string result = "";
for(int j = 0; j < input.Length; j++)
{
result += input[j];
if((i & (1 << j)) != 0) { result += "."; }
}
allPossibilities.Add(result);
System.Console.WriteLine(result);
}
If you're just looking to not add the item to the list if it's already there then, try this:
Change
allPossibilities.Add(result);
To
if (!allPossibilities.Contains(result)) { allPossibilities.Add(result); }
try this code, I know it's a little bit too much, but it's structured and I use bitmask for putting dot between characters.
static void Main(string[] args)
{
Do("qwerty");
}
public static void Do(string text)
{
int i = 1;
Text output = new Text();
output.Add(new Dot(i));
i = i * 2;
foreach(char c in text)
{
output.Add(new textChar(c));
output.Add(new Dot(i));
i = i * 2;
}
int possibilites = output.Possibilites;
for (i = 0; i < possibilites; i++)
{
Console.WriteLine(output.ToString(i));
}
}
public class Text
{
public List<character> characters = new List<character>();
public void Add(character c)
{
characters.Add(c);
}
public int Possibilites
{
get
{
return Convert.ToInt32(Math.Pow(2, characters.Count(C => C is Dot)));
}
}
public string ToString(int i)
{
string output = "";
foreach (character c in characters)
{
if (c is textChar)
{
output += c.c;
}
else if (c is Dot)
{
if ((i & ((Dot)c).index) != 0)
output += c.c;
}
}
return output;
}
}
public class character
{
public char c { set; get; }
}
public class textChar : character
{
public textChar(char c)
{
this.c = c;
}
}
public class Dot : character
{
public int index;
public Dot(int i)
{
index = i;
c = '.';
}
}
Another solution which works.
Here the positions of the dots get saved as a matrix in the binarycount List as booleans. They define where the dots will be.
static void Main(string[] args)
{
Console.WriteLine(String.Join(Environment.NewLine, printPossibilities("qwerty")));
}
private static List<string> printPossibilities(string str)
{
List<string> allPossibilities = new List<string>();
List<bool> binarycount = new List<bool>();
for (int i = 0; i < str.Length - 1; i++) {
binarycount.Add(false);
}
bool hasNext = true;
while(hasNext)
{
string temp = str;
for (int i = binarycount.Count - 1; i >= 0; i--)
{
if (binarycount[i])
temp = temp.Insert(i+1, ".");
}
allPossibilities.Add(temp);
hasNext = false;
for (int i = binarycount.Count - 1; i >= 0; i--)
{
if (binarycount[i]) {
binarycount[i] = false;
} else {
binarycount[i] = true;
hasNext = true;
break;
}
}
}
return allPossibilities;
}
output:
qwerty
qwert.y
qwer.ty
qwer.t.y
qwe.rty
qwe.rt.y
qwe.r.ty
qwe.r.t.y
qw.erty
qw.ert.y
qw.er.ty
qw.er.t.y
qw.e.rty
qw.e.rt.y
qw.e.r.ty
qw.e.r.t.y
q.werty
q.wert.y
q.wer.ty
q.wer.t.y
q.we.rty
q.we.rt.y
q.we.r.ty
q.we.r.t.y
q.w.erty
q.w.ert.y
q.w.er.ty
q.w.er.t.y
q.w.e.rty
q.w.e.rt.y
q.w.e.r.ty
q.w.e.r.t.y

Opposite method of math power adding numbers

I have method for converting array of Booleans to integer. It looks like this
class Program
{
public static int GivMeInt(bool[] outputs)
{
int data = 0;
for (int i = 0; i < 8; i++)
{
data += ((outputs[i] == true) ? Convert.ToInt32(Math.Pow(2, i)) : 0);
}
return data;
}
static void Main(string[] args)
{
bool[] outputs = new bool[8];
outputs[0] = false;
outputs[1] = true;
outputs[2] = false;
outputs[3] = true;
outputs[4] = false;
outputs[5] = false;
outputs[6] = false;
outputs[7] = false;
int data = GivMeInt(outputs);
Console.WriteLine(data);
Console.ReadKey();
}
}
Now I want to make opposite method returning array of Booleans values
As I am short with knowledge of .NET and C# until now I have only my mind hardcoding of switch statement or if conditions for every possible int value.
public static bool[] GiveMeBool(int data)
{
bool[] outputs = new bool[8];
if (data == 0)
{
outputs[0] = false;
outputs[1] = false;
outputs[2] = false;
outputs[3] = false;
outputs[4] = false;
outputs[5] = false;
outputs[6] = false;
outputs[7] = false;
}
//After thousand lines of coed
if (data == 255)
{
outputs[0] = true;
outputs[1] = true;
outputs[2] = true;
outputs[3] = true;
outputs[4] = true;
outputs[5] = true;
outputs[6] = true;
outputs[7] = true;
}
return outputs;
}
I know that there must be easier way.
You need to use bitwise operators: (Tested)
public static bool[] GiveMeBool(int data) {
bool[] outputs = new bool[8];
for(int i = 0; i < 8; i++)
outputs[i] = (data & (1 << i)) == (1 << i);
return outputs;
}
You can also use bitwise operators to make your original much faster: (Untested)
public static int GivMeInt(bool[] outputs) {
int data = 0;
for (int i = 0; i < 8; i++)
data += outputs[i] ? 1 << i : 0;
return data;
}
This uses bit shifting.
public static bool[] GiveMeBool(Int32 data)
{
bool[] bits = new bool[32];
for (i = 0; i <= bits.Length - 1; i++) {
bits(i) = (data & 1) == 1;
data >>= 1;
}
return bits;
}
This whole thing can be changed to use bitmaps using shift operators.
Try this...
public static bool[] GiveMeBool(int data)
{
bool[] outputs = new bool[8];
for (int i = 0; i < 8; i++)
outputs[i] = (data & (int)Math.Pow(2, i)) != 0;
return outputs;
}
What about something like the following?
Int32 x = 0xFF33;
bool[] retval = new bool[32];
for (int i = 0; i < 32 && x != 0; i++, x = x >> 1)
{
retval[i] = (x & 1) == 1;
}
It uses bit-shifting to do its magic.
I tested the methods in Java. The only significant difference is the bool vs boolean keywords.
public class Test {
public static void main(String[] args) {
boolean[] bools = new boolean[]{true,true,false,false,false,false,false,false};
int num = GivMeInt(bools);
boolean[] bools2 = GivMeBools(num);
for(int i = 0; i < 8; i++) System.out.println(bools[i]==bools2[i]);
}
public static int GivMeInt(boolean[] outputs)
{
int data = 0;
for (int i = 0; i < 8; i++)
{
if(outputs[i]) {
data += (1 << i);
}
}
return data;
}
public static boolean[] GivMeBools(int input)
{
boolean[] outputs = new boolean[8];
for (int i = 0; i < 8; i++)
{
outputs[i] = (input & 0x1) == 1;
input = input >>> 1;
}
return outputs;
}
}

Categories