Replacing all the empty elements in an array with a String value - c#

I have an array which can hold 10 elements:
string[] Ar = new string[10];
But it has only 5 items added to it. I need to insert The string value "NULL" to the rest of the empty slots in the array and thus making the array 'full' with string elements (that, being my objective).
This is what I've attempted as of now:
int entityCount = 5;
if (entityCount < 10)
{
for (int i = entityCount; i < 10; i++)
{
Ar[i] = "NULL";
}
}
And thus, when printed should output the values:
A, B, C, D, E, NULL, NULL, NULL, NULL, NULL
But this does not seem to do the trick, Still prints out ONLY the 5 items and not the 5 new strings.

I am not from C# background but I think this is what you want:
string[] Ar = new string[10];
for (int i = 0; i < 10; i++)
{
if(String.IsNullOrEmpty(Ar[i]))
{
Ar[i]="NULL";
}
}
for (int i = 0; i < 10; i++)
{
Console.WriteLine(Ar[i]);
}
You can read about String.IsNullOrEmpty(Ar[i]) here.

static void Main(string[] args)
{
int arraySize = 10;
string[] Ar = new string[arraySize];
Ar[0] = "A";
Ar[1] = "B";
Ar[2] = "C";
Ar[3] = "D";
for (int i = 0; i < arraySize; i++)
{
if (Ar[i]==null)
{
Ar[i] = "NULL";
}
}
for (int i = 0; i < Ar.Length; i++)
{
Console.Write(Ar[i]+" ");
}
}
}

this works fine.
int entityCount = 5;
string[] Ar = new string[10];
Ar[0] = "A";
Ar[1] = "B";
Ar[2] = "C";
Ar[3] = "D";
Ar[4] = "E";
if(entityCount < 10) {
for(int i = entityCount; i < 10; i++) {
Ar[i] = "NULL";
}
}
foreach(string s in Ar) {
Console.WriteLine(s);
}

using System;
using System.Linq;
class Program
{
private static void Main(string[] args)
{
string[] Ar = new string[10];
var item = from f in Ar
select string.IsNullOrWhiteSpace(f) ? "NULL" : f;
foreach (var i in item)
{
Console.WriteLine(i);
}
Console.ReadLine();
}
}

Here item is iterator in string of array replace all with null if not contains value
string multiplayer = new string[5];
foreach (var item in multiplayers)
{
if (item == null) { Console.WriteLine("Empty"); }
Console.WriteLine(item);
}
remember string of array is not nullable here

Related

I want to read a table from text file and assign each column to an array

i want to store each row in a different array. below is the code i tried.
but it doesn't not work, it only splits the last line and store values in "valueperline" array
first 11 rows are source text. file and screen shot of console
using System;
using System.Collections.Generic;
using System.IO;
namespace BBS_optimize
{
class Program
{
static void Main()
{
int i = 0; int j = 0; int k =0; string[] valueperline = new string[0]; string[] lines = new string [0];
lines = File.ReadAllLines("Table1.txt");
for (i = 0; i < lines.Length; i++)
{
Console.WriteLine(lines[i]);
}
for (j = 0; j<lines.Length; j++)
{ valueperline = lines[j].Split('\t');
}
for (k = 0; k < 44; k++)
{ Console.WriteLine(valueperline[k]);
}
}
}
}
Use array:
string[,] ParseFromFile (string fileName)
{
// Assume that your table have 10 cols and 100 rows
string[,] result = new string[10,100];
string str = File.ReadAllText (fileName);
// Split each line to arrays
string[] yourStringArray = str.Split(new[]{'\r', '\n'},StringSplitOptions.RemoveEmptyEntries);
for (int i == 0; i < yourStringArray; i++)
{
string[] row = yourStringArray[i].Split(new[]{" "},StringSplitOptions.RemoveEmptyEntries);
result[i] = row;
}
return result;
}
Use List:
List<List<string>> ParseFromFile (string fileName)
{
// Your list
List<List<string>> result = new List<List<string>>();
string str = File.ReadAllText (fileName);
// Split each line to arrays
string[] yourStringArray = str.Split(new[]{'\r', '\n'},StringSplitOptions.RemoveEmptyEntries);
for (int i == 0; i < yourStringArray; i++)
{
List<string> row = yourStringArray[i].Split(new[]{" "},StringSplitOptions.RemoveEmptyEntries).ToList();
result.Add(row);
}
return result;
}
below is a solution:
static void Main(string[] args)
{
List<List<string>> lst = new List<List<string>>();
string[] lines = new string[0];
lines = File.ReadAllLines("tableX.txt");
for (int i = 0; i < lines.Length; i++)
{
Console.WriteLine(lines[i]);
}
for (int j = 0; j < lines.Length; j++)
{
var line = lines[j].Split(' ').ToList();
lst.Add(line);
}
foreach (var item in lst)
{
for (int k = 0; k < item.Count; k++)
{
Console.WriteLine(item[k]);
}
}
}

Trying to write my void method as a string array method

I created a sort method that takes in a string array and sorts it alphabetically. However, I made a void method, not thinking about the fact that I can't really write a void method's data to a file, which is what I am trying to do. So now I am having trouble converting my method to a string array method as opposed to the void method. Can someone please point me in the right direction?
public void Sort(String[] arr)
{
String temp = "";
for (int i = 0; i < arr.Length; i++)
{
for (int j = i + 1; j < arr.Length; j++)
{
if (arr[i].CompareTo(arr[j]) > 0)
{
temp = arr[j];
arr[j] = arr[i];
arr[i] = temp;
}
}
Console.WriteLine(arr[i]);
}
}
updated code with my call to method:
class InsertionSort
{
public static string[] Sort(String[] arr)
{
String temp = "";
for (int i = 0; i < arr.Length; i++)
{
for (int j = i + 1; j < arr.Length; j++)
{
if (arr[i].CompareTo(arr[j]) > 0)
{
temp = arr[j];
arr[j] = arr[i];
arr[i] = temp;
}
}
}
return arr;
}
}
}
class Program
{
static void Main(string[] args)
{
String[] words = File.ReadLines("jumbled english FILTERED.ALL.txt").ToArray();
String[] sortedWords = InsertionSort.Sort(words);
System.IO.File.WriteAllLines("sortedtext.txt", sortedWords);
}
}
}
my code
what it prints
using System;
namespace ConsoleApp1
{
class Program
{
static void Main(string[] args)
{
String[] arr = new String[3];
arr[0] = "B";
arr[1] = "C";
arr[2] = "A";
Console.WriteLine(arr[0]);
Console.WriteLine(arr[1]);
Console.WriteLine(arr[2]);
Sort(arr);
Console.WriteLine(arr[0]);
Console.WriteLine(arr[1]);
Console.WriteLine(arr[2]);
using (System.IO.StreamWriter file = new System.IO.StreamWriter(#"C:\Test\Result.txt"))
{
foreach (string str in arr)
{
file.WriteLine(str);
}
}
Console.ReadLine();
}
public static void Sort(String[] arr)
{
String temp = "";
for (int i = 0; i < arr.Length; i++)
{
for (int j = i + 1; j < arr.Length; j++)
{
if (arr[i].CompareTo(arr[j]) > 0)
{
temp = arr[j];
arr[j] = arr[i];
arr[i] = temp;
}
}
//Console.WriteLine(arr[i]);
}
}
}
}
Result :
Ben,
Let me try to answer your question in two parts.
First, you wanted to return values from the method. For this, you need to change the return Type to string[] and return the arr after processing
public string[] Sort(string[] arr)
{
string temp = "";
for (int i = 0; i < arr.Length; i++)
{
for (int j = i + 1; j < arr.Length; j++)
{
if (arr[i].CompareTo(arr[j]) > 0)
{
temp = arr[j];
arr[j] = arr[i];
arr[i] = temp;
}
}
}
return arr;
}
Second part, you mentioned in comment that you want to write this to a file. You can use System.IO.File.WriteLineAllLines method to write to a file.
var input = new []{ "First line", "Third line" , "Second line" };
string[] lines = Sort(input);
System.IO.File.WriteAllLines(#"OutputFile.txt", lines);
To read more on writing contents to a file, please refer
Why make your own sorter and not use Array.Sort?
var lines = new[] { "one", "two", "three", "four" };
Array.Sort(lines, StringComparer.Ordinal);
System.IO.File.WriteAllLines("file.txt", lines);
I don't know why you creating such method as we have already linq to do such thing.
You can do this way. I hope it will work for you.
string[] words = { "India", "England", "America", "China", "Australia" };
string[] Ascending = words.OrderBy(c => c).Select(c=>c).ToArray(); // Ascending order
string[] Descending = words.OrderByDescending(c => c).Select(c => c).ToArray(); // Ascending order
foreach (var item in Ascending)
{
Console.WriteLine(item);
}
foreach (var item in Descending)
{
Console.WriteLine(item);
}

Arrange strings in alphabetical order

//code with problem (maybe)
numberArray = NameNumEquv;
listStringArray = NamesArray;
string[] sortedArray = new string[NamesArray.Length];
for (int arrayItemCounter = 0; arrayItemCounter < NamesArray.Length; arrayItemCounter++)
{
compareArrayCount = 1;
initialArrayCount = 0;
while (compareArrayCount < numberArray.Length)
{
for (int doubleArrayLength = 0; doubleArrayLength < numberArray[compareArrayCount].Length; doubleArrayLength++)
{
if (numberArray[initialArrayCount][doubleArrayLength] < numberArray[compareArrayCount][doubleArrayLength])
{
initialArrayCount = compareArrayCount;
break;
}
}
compareArrayCount = compareArrayCount + 1;
}
sortedArray[arrayItemCounter] = listStringArray[initialArrayCount];
List<string> tempArrayValues = new List<string>();
List<int[]> tempNumArrayValues = new List<int[]>();
for (int tempArrayCount = 0; tempArrayCount < listStringArray.Length; tempArrayCount++)
{
if (tempArrayCount != initialArrayCount)
{
tempArrayValues.Add(listStringArray[tempArrayCount]);
tempNumArrayValues.Add(numberArray[tempArrayCount]);
}
}
listStringArray = tempArrayValues.ToArray();
numberArray = tempNumArrayValues.ToArray();
tempArrayValues.Clear();
tempNumArrayValues.Clear();
}
//till here
foreach (string nums in sortedArray)
{
Console.WriteLine(nums);
}
}
public static int[] AlphaNumericConversion(string stringValue, int arrayLength)
{
string Alphabets = "abcdefghijklmnopqrstuvwxyz";
char[] alphabetArray = Alphabets.ToCharArray();
string lowerCaseConv = stringValue.ToLower();
char[] stringArray = lowerCaseConv.ToCharArray();
int[] numericalConvertedArray = new int[arrayLength];
for (int valueArrayCount = 0; valueArrayCount < numericalConvertedArray.Length; valueArrayCount++)
{
numericalConvertedArray[valueArrayCount] = 0;
}
for (int letterCounter= 0;letterCounter < stringArray.Length;letterCounter++)
{
for (int alphabetCounter = 0; alphabetCounter < Alphabets.Length; alphabetCounter++)
{
if (stringArray[letterCounter] == alphabetArray[alphabetCounter])
numericalConvertedArray[letterCounter] = alphabetCounter + 1;
}
}
return numericalConvertedArray;
}
}
}
I want to arrange strings in ascending order. It is arranging the single letter strings(a, b, c,d, e.....) in reverse alphabetical order as in Z-A and string containing 2 or more letters randomly such as "Aayush", "Ayush", "Aayusha", "Ayusha" to "Aayusha","Ayusha","Aayush","Ayush". What is wrong with the code. Don't suggest to simply use List.Sort() because I want to write it in algorithmic manner. I'm trying to understand how it works rather than using Sort().

Threading in c# to build a distributed DFS

I have been trying to implement a distributed depth first search in c#. I have beem successful upto a certain point but have got a synchronisation error. I am not able to rectify the error. What i am trying to do is make each node communicate with one other using task parallel dataflow and thereby i attain parallelism in DFS. Below is my code:
public class DFS
{
static List<string> traversedList = new List<string>();
static List<string> parentList = new List<string>();
static Thread[] thread_array;
static BufferBlock<Object> buffer1 = new BufferBlock<Object>();
public static void Main(string[] args)
{
int N = 100;
int M = N * 4;
int P = N * 16;
Stopwatch stopwatch = new Stopwatch();
stopwatch.Start();
List<string> global_list = new List<string>();
StreamReader file = new StreamReader(args[args.Length - 2]);
string text = file.ReadToEnd();
string[] lines = text.Split('\n');
string[][] array1 = new string[lines.Length][];
for (int i = 0; i < lines.Length; i++)
{
lines[i] = lines[i].Trim();
string[] words = lines[i].Split(' ');
array1[i] = new string[words.Length];
for (int j = 0; j < words.Length; j++)
{
array1[i][j] = words[j];
}
}
StreamWriter sr = new StreamWriter("E:\\Newtext1.txt");
for (int i = 0; i < array1.Length; i++)
{
for (int j = 0; j < array1[i].Length; j++)
{
if (j != 0)
{
sr.Write(array1[i][0] + ":" + array1[i][j]);
Console.WriteLine(array1[i][0] + ":" + array1[i][j]);
sr.Write(sr.NewLine);
}
}
}
int start_no = Convert.ToInt32(args[args.Length - 1]);
thread_array = new Thread[lines.Length];
string first_message = "root";
buffer1.Post(first_message);
buffer1.Post(array1);
buffer1.Post(start_no);
buffer1.Post(1);
for (int t = 1; t < lines.Length; t++)
{
Console.WriteLine("thread" + t);
thread_array[t] = new Thread(new ThreadStart(thread_run));
thread_array[t].Name = t.ToString();
lock (thread_array[t])
{
Console.WriteLine("working");
thread_array[t].Start();
thread_array[t].Join();
}
}
stopwatch.Stop();
Console.WriteLine(stopwatch.Elapsed);
Console.ReadLine();
}
private static void dfs(string[][] array, int point)
{
for (int z = 1; z < array[point].Length; z++)
{
if ((!traversedList.Contains(array[point][z])))
{
traversedList.Add(array[point][z]);
parentList.Add(point.ToString());
dfs(array, int.Parse(array[point][z]));
}
}
return;
}
public static void thread_run()
{
try
{
string parent;
string[][] array1;
int point;
int id;
parent = (string)buffer1.Receive();
array1 = (string[][])buffer1.Receive();
point = (int)buffer1.Receive();
id = (int)buffer1.Receive();
object value;
Console.WriteLine("times");
if (Thread.CurrentThread.Name.Equals(point.ToString()))
{
if (!traversedList.Contains(point.ToString()))
{
Console.WriteLine("Node:" + point + " Parent:" + parent + " Id:" + id);
traversedList.Add(point.ToString());
parent = point.ToString();
for (int x = 1; x < array1[point].Length; x++)
{
Console.WriteLine("times");
if (buffer1.TryReceive(out value))
{
array1 = (string[][])value;
}
if (buffer1.TryReceive(out value))
{
id = (int)buffer1.Receive();
}
id++;
buffer1.Post(parent);
buffer1.Post(array1);
buffer1.Post(x);
buffer1.Post(id);
Console.WriteLine("times");
Monitor.PulseAll(Thread.CurrentThread);
}
//return;
}
else
{
buffer1.Post(parent);
buffer1.Post(array1);
buffer1.Post(point);
buffer1.Post(id);
Console.WriteLine("working 1");
Monitor.PulseAll(Thread.CurrentThread);
}
}
else
{
Console.WriteLine("working 2");
Monitor.Wait(Thread.CurrentThread);
}
//Console.WriteLine(parent);
}
catch (Exception ex)
{
Console.WriteLine(ex.Message);
}
}
}
There various issues with your code.
Incorrect use of locking and "touching" the traversedList from multiple threads is the most obvious problem.
More importantly, your code doesn't really use Dataflow, it uses BufferBlock in a manner similar to ConcurrentQueue or any other concurrent collection. The whole point of dataflow is to use ActionBlocks instead of threads to simplify processing. By default an action block will use only a single thread for processing but you can specify as many threads as you want through the DataflowBlockOptions class.
ActionBlocks have their own input and output buffers so you don't have to add additional BufferBlocks just for buffering.
Passing multiple related values to a block is another problem, as it can lead to errors and makes the code confusing. Creating a data structure to hold all the values doesn't cost anything.
Assuming you use this class to hold processing message:
public class PointMessage
{
public string Message { get; set; }
public string[][] Lines{get;set;}
public int Point { get; set; }
public int ID { get; set; }
}
You can create an ActionBlock to process these messages like this:
static ActionBlock<PointMessage> _block;
...
var options = new ExecutionDataflowBlockOptions { MaxDegreeOfParallelism = ExecutionDataflowBlockOptions.Unbounded };
_block=new ActionBlock<PointMessage>(msg=>ProcessMessage(msg),options);
And process each message like this:
private static void ProcessMessage(PointMessage arg)
{
if (...)
{
...
arg.ID++;
_block.Post(arg);
}
else
{
...
_block.Post(arg);
}
}
If your function returns a value, you can use a TransformBlock instead of an ActionBlock.
I don't understand what your code does so I won't try to rewrite it using DataFlow. If you clean it up a bit, it will be easier to help.
The issue is that the Thread needs to own Monitor in order to call Wait. So you need to lock on Monitor.PulseAll aswell as Monitor.Wait in order to ensure that you don't get any more errors like this.
If you need me to explain locking to you, open another question and I'll explain it in full! :)
EDIT: Ignore my post - Read the post from #PanagiotisKanavos instead...
This won't compile, but will set you in the right direction for using locks:
using System;
using System.Collections.Generic;
using System.Diagnostics;
using System.IO;
using System.Threading;
public class DFS
{
static List<string> traversedList = new List<string>();
static List<string> parentList = new List<string>();
static Thread[] thread_array;
//static BufferBlock<Object> buffer1 = new BufferBlock<Object>();
public static void Main(string[] args)
{
int N = 100;
int M = N * 4;
int P = N * 16;
Stopwatch stopwatch = new Stopwatch();
stopwatch.Start();
List<string> global_list = new List<string>();
StreamReader file = new StreamReader(args[args.Length - 2]);
string text = file.ReadToEnd();
string[] lines = text.Split('\n');
string[][] array1 = new string[lines.Length][];
for (int i = 0; i < lines.Length; i++)
{
lines[i] = lines[i].Trim();
string[] words = lines[i].Split(' ');
array1[i] = new string[words.Length];
for (int j = 0; j < words.Length; j++)
{
array1[i][j] = words[j];
}
}
StreamWriter sr = new StreamWriter("E:\\Newtext1.txt");
for (int i = 0; i < array1.Length; i++)
{
for (int j = 0; j < array1[i].Length; j++)
{
if (j != 0)
{
sr.Write(array1[i][0] + ":" + array1[i][j]);
Console.WriteLine(array1[i][0] + ":" + array1[i][j]);
sr.Write(sr.NewLine);
}
}
}
int start_no = Convert.ToInt32(args[args.Length - 1]);
thread_array = new Thread[lines.Length];
string first_message = "root";
//buffer1.Post(first_message);
//buffer1.Post(array1);
//buffer1.Post(start_no);
//buffer1.Post(1);
for (int t = 1; t < lines.Length; t++)
{
Console.WriteLine("thread" + t);
thread_array[t] = new Thread(new ThreadStart(thread_run));
thread_array[t].Name = t.ToString();
lock (thread_array[t])
{
Console.WriteLine("working");
thread_array[t].Start();
thread_array[t].Join();
}
}
stopwatch.Stop();
Console.WriteLine(stopwatch.Elapsed);
Console.ReadLine();
}
private static void dfs(string[][] array, int point)
{
for (int z = 1; z < array[point].Length; z++)
{
if ((!traversedList.Contains(array[point][z])))
{
traversedList.Add(array[point][z]);
parentList.Add(point.ToString());
dfs(array, int.Parse(array[point][z]));
}
}
return;
}
bool busy;
private readonly object syncLock = new object();
public static void thread_run()
{
try
{
string parent;
string[][] array1;
int point;
int id;
//parent = (string)buffer1.Receive();
//array1 = (string[][])buffer1.Receive();
//point = (int)buffer1.Receive();
//id = (int)buffer1.Receive();
object value;
Console.WriteLine("times");
if (Thread.CurrentThread.Name.Equals("Point.ToString()"))
{
if (!traversedList.Contains("Point.ToString()"))
{
for (int x = 1; x < 99999; x++)
{
Console.WriteLine("times");
//if (buffer1.TryReceive(out value))
//{
// array1 = (string[][])value;
//}
//if (buffer1.TryReceive(out value))
//{
// id = (int)buffer1.Receive();
//}
//id++;
//buffer1.Post(parent);
//buffer1.Post(array1);
//buffer1.Post(x);
//buffer1.Post(id);
Console.WriteLine("times");
lock (syncLock)
{
while (busy)
{
busy = false;
Monitor.PulseAll(Thread.CurrentThread);
}
busy = true; // we've got it!
}
}
//return;
}
else
{
//buffer1.Post(parent);
//buffer1.Post(array1);
//buffer1.Post(point);
//buffer1.Post(id);
lock (syncLock)
{
while (busy)
{
busy = false;
Monitor.PulseAll(Thread.CurrentThread);
}
busy = true; // we've got it!
}
}
}
else
{
Console.WriteLine("working 2");
lock (syncLock)
{
while (busy)
{
Monitor.Wait(Thread.CurrentThread);
}
busy = true; // we've got it!
}
}
//Console.WriteLine(parent);
}
catch (Exception ex)
{
Console.WriteLine(ex.Message);
}
}
}

Function that generates strings according to input

I need a C# function that takes 2 strings as an input and return an array of all possible combinations of strings.
private string[] FunctionName(string string1, string string2)
{
//code
}
The strings input will be in the following format:
string1: basement
string2: a*fa
Now what I need is all combinations of possible strings using the characters in String2 (ignoring the * symbols), and keeping them in the same character position like this:
baaement, baaefent, baaefena, basefent, basemena, etc.
EDIT:
This is not homework. I need this function for a piece of a program I am doing.
The following is the code I have so far but it has some bugs.
static List<string> combinations = new List<string>();
static void Main(string[] args)
{
//include trimming of input string
string FoundRes = "incoming";
string AltRes = "*2*45*78";
List<int> loc = new List<int>();
string word = "";
for (int i = 0; i < AltRes.Length; i++)
{
if (AltRes[i] != '*')
{
loc.Add(i);
word += AltRes[i];
}
}
generate(word);
string[] aaa = InsertSymbol(FoundRes, loc.ToArray(), AltRes, combinations);
Console.WriteLine("input string: " + FoundRes);
Console.WriteLine("Substitute string: " + AltRes);
Console.WriteLine("============Output============");
for (int j = 0; j < aaa.Length; j++)
{
Console.WriteLine(aaa[j]);
}
Console.ReadKey();
}//
private static void generate(string word)
{
// Add this word to combination results set
if (!combinations.Contains(word))
combinations.Add(word);
// If the word has only one character, break the recursion
if (word.Length == 1)
{
if (!combinations.Contains(word))
combinations.Add(word);
return;
}
// Go through every position of the word
for (int i = 0; i < word.Length; i++)
{
// Remove the character at the current position
// call this method with the String
generate(word.Substring(0, i) + word.Substring(i + 1));
}
}//
private static string[] InsertSymbol(string orig, int[] loc, string alternative, List<string> Chars)
{
List<string> CombinationsList = new List<string>();
string temp = "";
for (int i = 0; i < Chars.Count; i++)
{
temp = orig;
for (int j = 0; j < Chars[i].Length; j++)
{
string token = Chars[i];
if (alternative.IndexOf(token[j]) == loc[j])
{
temp = temp.Remove(loc[j], 1);
temp = temp.Insert(loc[j], token[j].ToString());
// int pos = sourceSubst.IndexOf(token[j]);
// sourceSubst = sourceSubst.Remove(pos, 1);
// sourceSubst = sourceSubst.Insert(pos, ".");
}
else
{
temp = temp.Remove(alternative.IndexOf(token[j]), 1);
temp = temp.Insert(alternative.IndexOf(token[j]), token[j].ToString());
}
}
CombinationsList.Add(temp);
}
return CombinationsList.ToArray();
}//
It does sound like homework. As a suggestion, I would ignore the first parameter and focus on getting all possible permutations of the second string. What's turned off, what's turned on, etc. From that list, you can easily come up with a method of swapping out characters of the first string.
On that note, I'm in the uncomfortable position of having a function ready to go but not wanting to post it because of the homework implication. I'd sure love for somebody to review it, though! And technically, there's two functions involved because I just happened to already have a generic function to generate subsets lying around.
Edit: OP says it isn't homework, so here is what I came up with. It has been refactored a bit since the claim of two functions, and I'm more than open to criticism.
using System;
using System.Collections.Generic;
using System.Text;
class Program
{
static void Main()
{
string original = "phenomenal";
string pattern = "*xo**q*t**";
string[] replacements = StringUtility.GetReplacementStrings(original, pattern, true);
foreach (string replacement in replacements)
Console.WriteLine(replacement);
Console.Read();
}
public static class StringUtility
{
public static string[] GetReplacementStrings(string original, string pattern, bool includeOriginal)
{
// pattern and original might not be same length
int maxIndex = Math.Max(original.Length, pattern.Length);
List<int> positions = GetPatternPositions(pattern, maxIndex, '*');
List<int[]> subsets = ArrayUtility.CreateSubsets(positions.ToArray());
List<string> replacements = GenerateReplacements(original, pattern, subsets);
if (includeOriginal)
replacements.Insert(0, original);
return replacements.ToArray();
}
private static List<string> GenerateReplacements(string original, string pattern, List<int[]> subsets)
{
List<string> replacements = new List<string>();
char[] temp = new char[original.Length];
foreach (int[] subset in subsets)
{
original.CopyTo(0, temp, 0, original.Length);
foreach (int index in subset)
{
temp[index] = pattern[index];
}
replacements.Add(new string(temp));
}
return replacements;
}
private static List<int> GetPatternPositions(string pattern, int maxIndex, char excludeCharacter)
{
List<int> positions = new List<int>();
for (int i = 0; i < maxIndex; i++)
{
if (pattern[i] != excludeCharacter)
positions.Add(i);
}
return positions;
}
}
public static class ArrayUtility
{
public static List<T[]> CreateSubsets<T>(T[] originalArray)
{
List<T[]> subsets = new List<T[]>();
for (int i = 0; i < originalArray.Length; i++)
{
int subsetCount = subsets.Count;
subsets.Add(new T[] { originalArray[i] });
for (int j = 0; j < subsetCount; j++)
{
T[] newSubset = new T[subsets[j].Length + 1];
subsets[j].CopyTo(newSubset, 0);
newSubset[newSubset.Length - 1] = originalArray[i];
subsets.Add(newSubset);
}
}
return subsets;
}
}
}
since it's hopw work I'd only suggest some way to solve the problem rather than writing the code.
if you loop the second parameter every time you hit a letter you'll have to options either use the letter from the first argument or the letter from the second. collect all these optins together with the index. keep a list of the parts from the first argument that will never change. iterate thorugh those two lists to created all the possible permutations
Decimal to Binary converted code is stolon copied from here.
static void Main()
{
string string1 = "basement";
string string2 = "**a*f**a";
string[] result = GetCombinations(string1, string2);
foreach (var item in result)
{
Console.WriteLine(item);
}
}
private static string[] GetCombinations(string string1, string string2)
{
var list = new List<List<char>> { new List<char>(), new List<char>() };
var cl = new List<char>();
List<string> result = new List<string>();
for (int i = 0; i < string1.Length; i++)
{
if (string2[i] == '*')
{
cl.Add(string1[i]);
}
else
{
list[0].Add(string1[i]);
list[1].Add(string2[i]);
}
}
int l = list[0].Count;
for (int i = 0; i < (Int64)Math.Pow(2.0,l); i++)
{
string s = ToBinary(i, l);
string ss = "";
int x = 0;
int y = 0;
for (int I = 0; I < string1.Length; I++)
{
if (string2[I] == '*')
{
ss += cl[x].ToString();
x++;
}
else
{
ss += (list[int.Parse(s[y].ToString())][y]);
y++;
}
}
result.Add(ss);
}
return result.ToArray<string>();
}
public static string ToBinary(Int64 Decimal, int width)
{
Int64 BinaryHolder;
char[] BinaryArray;
string BinaryResult = "";
while (Decimal > 0)
{
BinaryHolder = Decimal % 2;
BinaryResult += BinaryHolder;
Decimal = Decimal / 2;
}
BinaryArray = BinaryResult.ToCharArray();
Array.Reverse(BinaryArray);
BinaryResult = new string(BinaryArray);
var d = width - BinaryResult.Length;
if (d != 0) for (int i = 0; i < d; i++) BinaryResult = "0" + BinaryResult;
return BinaryResult;
}
which password cracker do you want to program? :)
how about
if string2 contains '*'
foreach(char ch in string1)
replace first * with ch,
execute FunctionName
else
print string2

Categories

Resources