how to fix stringBuilder to string and reverse? - c#

I have a StringBuilder result and I want to reverse it but in C# the StringBuilder doesn't support .Reverse() so first I cast it to a string and then I reverse it and add a "$" to the end of string.
but the answer is like this:
System.Linq.Enumerable+<ReverseIterator>d__75`1[System.Char]" string
how can I fix this?
StringBuilder result = new StringBuilder();
List<string> matrix = new List<string>();
List<int> indexes = new List<int>();
for (int i = 0; i < bwt.Length; i++)
{
matrix.Add("" + bwt[i]);
indexes.Add(i);
}
indexes.Sort((o1, o2) => matrix[o1].CompareTo(matrix[o2]));
int current = indexes[0];
for (int i = 0; i < bwt.Length - 1; i++)
{
int index = indexes.IndexOf(current);
string next = bwt[index].ToString();
result.Append(next);
current = index;
}
// return result.ToString().ToString() + "$";

StringBuilder allows you to access and manipulate the characters through their indexes.
string stringToReverse = "abcdefghijk";
var sb = new StringBuilder(stringToReverse);
for (int i = 0, j = sb.Length - 1; i < sb.Length / 2; i++, j--) {
char temp = sb[i];
sb[i] = sb[j];
sb[j] = temp;
}
string reversed = sb.ToString();
But I made a Test which shows that #Mendhak's version is faster. One million repetitions with strings of length 100
StringBuilder: 974 ms
Mendhak: 209 ms
So on my PC it takes just 209 ns to reverse the string with Mendhak's solution. Just because a solution looks faster it must not be faster. Array.Reverse calls the external method private static extern bool TrySZReverse(Array array, int index, int count); which is highly optimized.
The test:
static class ReverseString
{
const string stringToReverse = "abcdex.dfkjvhw4o5i8yd,vfjhe4iotuwyflkcjadhrlniqeuyfmln mclf8yuertoicer,tpoirsd,kfngoiw5r8t7ndlrgjhfg";
public static string TestStringBuilder()
{
var sb = new StringBuilder(stringToReverse);
for (int i = 0, j = sb.Length - 1; i < sb.Length / 2; i++, j--) {
char temp = sb[i];
sb[i] = sb[j];
sb[j] = temp;
}
return sb.ToString();
}
// By Mendhak
public static string TestArrayReverse()
{
char[] arr = stringToReverse.ToString().ToCharArray();
Array.Reverse(arr);
return new string(arr);
}
public static void Compare()
{
string result1 = TestStringBuilder();
string result2 = TestArrayReverse();
Console.WriteLine($"Are result1 and 2 equal? {result1 == result2}");
Measure("StringBuilder", TestStringBuilder);
Measure("Array.Reverse", TestArrayReverse);
Console.ReadKey();
}
public static void Measure(string method, Func<string> sut)
{
const int NTests = 1000000;
var stopWatch = new Stopwatch();
stopWatch.Start();
for (int i = 0; i < NTests; i++) {
sut();
}
stopWatch.Stop();
Console.WriteLine($"{method} = {stopWatch.ElapsedMilliseconds} ms");
}
}

You will need to take a few extra steps to reverse your string. Build it as you normally would in your stringbuilder (result), then
char[] arr = result.ToString().ToCharArray();
Array.Reverse(arr);
return new string(arr) + "$";

Related

c# split string by random length

lets say i have an string like the below:
AAAABBBBBBBBBBCCCC
Currently my code can only split the above string equally by the len that I use as parameter using the function below:
private static IEnumerable<string> SplitByLength(string str, int maxLength)
{
for (var index = 0; index < str.Length; index += maxLength)
yield return str.Substring(index, Math.Min(maxLength, str.Length - index));
}
but this isnt what i want, I want the string to be splitted to random len, lets say between 2 to 10 char. example:
AAA
ABBBBB
BB
BBBCCC
C
the split len should be random. any hints how can I make it?
Check this:
private static IEnumerable<string> SplitByLength(string str, int maxLength)
{
var random = new Random();
var count = Math.Min(random.Next(1, maxLength + 1), str.Length);
int index = 0;
while (index < str.Length)
{
yield return str.Substring(index, count);
index += count;
count = Math.Min(random.Next(1, maxLength + 1), str.Length - index);
}
}
This works.
private static List<string> SplitString(string input)
{
var result = new List<string>();
var tempString = input;
var testString = "";
while (true)
{
var maxInt = tempString.Length <= 35 ? tempString.Length : 35;
var minInt = tempString.Length <= 10 ? tempString.Length : 10;
var random1 = Random.Next(minInt, maxInt);
result.Add(tempString.Substring(0, random1));
testString += tempString.Substring(0, random1);
tempString = tempString.Remove(0, random1);
if (tempString.Length == 0)
{
break;
}
}
return result;
}

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

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.

Removing Leading Zeros in a Char Array

I'm attempting to subtract two strings (of theoretically infinite length) without the use of libraries like BigIntbut I was wondering if anybody has any good ideas on how to remove the leading zeros in the corner cases like the one below?
static void Main(string[] args)
{
Console.WriteLine(Subtract("10", "10005"));
}
static string ReverseInput(string inputString)
{
char[] charArray = inputString.ToCharArray();
Array.Reverse(charArray);
return new string(charArray);
}
static string Subtract(string firstNumInput, string secondNumInput)
{
string firstNum = String.Empty;
string secondNum = String.Empty;
bool negative = false;
// Reverse order of string input
if (firstNumInput.Length > secondNumInput.Length)
{
firstNum = ReverseInput(firstNumInput);
secondNum = ReverseInput(secondNumInput);
}
else if (firstNumInput.Length < secondNumInput.Length)
{
negative = true;
firstNum = ReverseInput(secondNumInput);
secondNum = ReverseInput(firstNumInput);
}
else if (firstNumInput.Length == secondNumInput.Length)
{
// iterate through string to find largest
}
char[] result = new char[firstNum.Length + 1];
int resultLength = 0;
int carry = 0;
for (int i = 0; i < firstNum.Length; i++)
{
int an = (i < firstNum.Length) ? int.Parse(firstNum[i].ToString()) : 0;
int bn = (i < secondNum.Length) ? int.Parse(secondNum[i].ToString()) : 0;
int rn = an - bn - carry;
if (rn < 0)
{
carry = 1;
rn += 10;
}
else
{
carry = 0;
}
result[resultLength++] = (char)(rn + '0');
}
// create the result string from the char array
string finalResult = ReverseInput(new string(result, 0, resultLength));
if (negative)
{
finalResult = '-' + finalResult;
}
return finalResult;
}
Are you looking for TrimStart?
// create the result string from the char array
string finalResult = ReverseInput(new string(result, 0, resultLength)).TrimStart('0');

C# printing and skipping a certain number of characters

Ok, here's the problem that I have: using C# I want to format a string by printing out a certain number of characters, then skipping a certain number of characters and then again print, skip.
For example: I want to print 3 characters by skipping the next 2.
So this:
ABCDEFGHIJKL
would become this:
ABCFGHKL
I have only made that it could skip every 2,3,4 and so on characters and I couldn't think of how to approach this further.
Here is so far what I have
string text;
int print = 3;
int skip = 2;
StreamReader file = new StreamReader(#"c:\test.txt");
while ((text = file.Readtext()) != null)
{
string[] stringArray = new string[text.Length];
char ch;
for (int i = 0; i < text.Length; i++)
{
ch = text[i];
stringArray[i] = ch.ToString();
}
for (int i = 0; i < stringArray.Length; i+=skip)
{
Console.Write(stringArray[i]);
}
}
Thanks.
Thank you guys for various great solutions, I really appreciate your help! Thanks!
int take = 3;
int skip = 2;
string s = "ABCDEFGHIJKL";
var newstr = String.Join("", s.Where((c,i) => i % (skip + take) < take));
EDIT
Here are my test results....
int take = 3;
int skip = 2;
string s = String.Join("",Enumerable.Repeat("0123456789", 200));
var t1 = Measure(10000, () => { var newstr = String.Join("", s.Where((c, i) => i % (skip + take) < take)); });
var t2 = Measure(10000, () => { var newstr = new string(s.Where((c, i) => i % (skip + take) < take).ToArray()); });
var t3 = Measure(10000, () => { var newstr = GetString(s, take, skip); });
long Measure(int n,Action action)
{
action(); //JIT???
var sw = Stopwatch.StartNew();
for (int i = 0; i < n; i++)
{
action();
}
return sw.ElapsedMilliseconds;
}
OUTPUT:
1665 ms. (String.Join)
1154 ms. (new string())
7457 ms. (Sayse's GetString)
EDIT 2
Modifying Sayse's answer as below gives the fastest result among the codes i tested. (311 ms)
public string GetString(string s, int substringLen, int skipCount)
{
StringBuilder newString = new StringBuilder(s.Length);
for (int i = 0; i < s.Length; i += skipCount)
{
for (int j = 0; j < substringLen && i < s.Length; j++)
{
newString.Append(s[i++]);
}
}
return newString.ToString();
}
I like I4V's answer more but heres one way to achieve this
public string GetString(string s, int substringLen, int skipCount)
{
string newString = "";
for (int i = 0; i < s.Length; i += skipCount)
{
for (int j = 0; j < substringLen && i < s.Length; j++)
{
newString += s[i++];
}
}
return newString;
}
Edit Benchmark stated my way was faster
var newStr2 = new Program().GetString(a, take, skip);
var newstr = String.Join("", a.Where((c, i) => i % (skip + take) < take));
sw.Start();
for (int i = 0; i < 1000000; i++)
{
newStr2 = new Program().GetString(a, take, skip);
}
sw.Stop();
Console.WriteLine("my way: " + sw.Elapsed.ToString());
sw.Reset();
sw.Start();
for (int i = 0; i < 1000000; i++)
{
newstr = String.Join("", a.Where((c, iv) => iv % (skip + take) < take));
}
sw.Stop();
Console.WriteLine("I4V way: " + sw.Elapsed.ToString());
Output
my way: 00:00:00.7634927
I4V way: 00:00:01.0183307
int print = 3;
int skip = 2;
Boolean isPrintState = true;
int statePosition = 0;
StringBuilder Sb = new StringBuilder();
using (TextReader reader = new StreamReader(#"c:\test.txt")) {
while (true) {
int Ch = reader.Read();
if (Ch < 0)
break;
statePosition += 1;
if ((isPrintState && (statePosition > print)) || (!isPrintState && (statePosition > skip))) {
statePosition = 1;
isPrintState = !isPrintState;
}
if (isPrintState)
Sb.Append((Char) Ch);
}
}
Console.Write(Sb.ToString());
Amidst so many good looking answer, mine might not be so sophisticated but I thought I would post it anyways. Simple logic.
var take = 3;
var skip = 2;
StringBuilder source = new StringBuilder("ABCDEFGHIJKL");
StringBuilder result = new StringBuilder();
while (source.Length > 0)
{
if (source.Length >= take)
{
result.Append(source.ToString().Substring(0, take));
}
else
{
result.Append(source.ToString());
}
if (source.Length > skip + take)
{
source.Remove(0, skip + take);
}
else
source.Clear();
}
This how to do that.
I think this may be more clear if you are not familiar with Lambda expression
int print = 3;
int skip = 2;
string str = "ABCDEFGHILKL";
StringBuilder stringBuilder = new StringBuilder();
string res = String.Empty;
int i = 0;
while (i < str.Length)
{
stringBuilder.Append(str.Substring(i, Math.Min(print, str.Length - i)));
i += print + skip;
}
Console.WriteLine(stringBuilder.ToString());

Categories