I'm trying to check if two words are anagram and trying to do this with LinkedList.To do that,first,I created a class named LinkedList:
class LinkedList
{
private Node head;
private int count;
public LinkedList()
{
this.head = null;
this.count = 0;
}
public bool Empty
{
get { return this.count == 0; }
}
public int Count
{
get { return this.count; }
}
public object this[int index]
{
get { return this.Get(index); }
}
public object Add(int index,object o)
{
if (index < 0)
{
throw new ArgumentOutOfRangeException("Index - " + index); //if index is less than 0 throw an error message
}
if (index > count) // if size exceeds the limit of the list the item will be added to the last line of the list.
{
index = count;
}
Node current = this.head;
if(this.Empty || index== 0)
{
this.head = new Node(o, this.head);
}
else
{
for(int i = 0; i < index - 1; i++)
{
current = current.Next;
}
current.Next = new Node(o, current.Next);
}
count++;
return o;
}
public object Add(Object o)
{
return this.Add(count, o);
}
public object Remove(int index)
{
if (index < 0)
{
throw new ArgumentOutOfRangeException("Index - " + index);
}
if (this.Empty)
{
return null;
}
if (index >= this.count)
{
index = count-1;
}
Node current = this.head;
object result = null;
if (index == 0)
{
result = current.Data; //gets the first node
this.head = current.Next; //makes 2nd node to the first node
}
else
{
for(int i = 0; i < index - 1; i++)
{
result = current.Next.Data;
}
result = current.Next;
current.Next = current.Next.Next;
}
count--;
return result;
}
public int IndexOf(object o)
{
Node current = this.head;
for(int i = 0; i < this.count; i++)
{
if (current.Data.Equals(o))
{
return i;
}
current = current.Next;
}
return -1;
}
public bool Contains(object o)
{
return this.IndexOf(o) >= 0; //if list contains object it returns bigger value than -1 and also 0.
}
public object Get(int index)
{
if(index < 0)
{
throw new ArgumentOutOfRangeException("Index - " + index);
}
if (this.Empty)
{
return null;
}
if(index >= this.count)
{
index = this.count-1;
}
Node current = this.head;
for(int i=0;i< index; i++)
{
current = current.Next;
}
return current.Data;
}
}
And another class named "Node":
class Node
{
private object data;
private Node next;
public Node(object data,Node next) //constructor
{
this.data = data;
this.next = next;
}
public object Data
{
get { return this.data; }
set { this.data = value; }
}
public Node Next
{
get { return this.next; }
set { this.next = value; }
}
}
And in main program,I created two objects from linkedlist class and read two strings from user and added the words' chars to the linked list.And compared the chars and if they found they'll be deleted from linkedlist,increases the counter and so on.If counter equals to the list1's number ofelements then they are anagrams if not the words are not anagrams.Here's my main program code:
class Program
{
static void Main(string[] args)
{
int counter = 0;
String word1, word2;
Console.WriteLine("Welcome to Anagram Checker!\nPlease enter your first word:");
word1 = Console.ReadLine();
Console.WriteLine("\nPlease enter the second word:");
word2 = Console.ReadLine();
int result = AnagramChecker(word1, word2, counter);
if (result == 1)
{
Console.WriteLine("These words are anagram");
}
if (result == 0)
{
Console.WriteLine("The words are not anagrams");
}
Console.ReadLine();
}
public static int AnagramChecker(String word1, String word2, int counter)
{
char[] ArrayWord1 = word1.ToCharArray();
char[] ArrayWord2 = word2.ToCharArray();
LinkedList list1 = new LinkedList();
LinkedList list2 = new LinkedList();
for (int i = 0; i < ArrayWord1.Length; i++) //Adds char of word1 to the list
{
list1.Add(i,ArrayWord1[i]);
}
for (int j = 0; j < ArrayWord2.Length; j++) //Adds char of word2 to the list
{
list2.Add(j,ArrayWord2[j]);
}
int max;
if (list1.Count >= list2.Count)
{
max = list1.Count;
}
if (list2.Count > list1.Count)
{
max = list2.Count;
}
for (int i = 0; i < list1.Count; i++)
{
if (list2.Contains(list1[i]) && list1.Contains(list2[i]))
{
list1.Remove(i);
list2.Remove(list2.IndexOf(list1[i]));
counter++;
}
}
Console.WriteLine(counter);
if (counter == word1.Length || counter == word2.Length)
{
return 1;
}
else
return 0;
}
}
When I'm entering different words I get different results.The output examples are below.What do I do wrong?
Outputs:
1-)
2-)
Thanks for your kind helps.
If you're just looking to find if words are anagrams, you can use this method:
private static bool areAnagrams(string word1, string word2)
{
List<char> w1 = word1.OrderBy(c => c).ToList();
List<char> w2 = word2.OrderBy(c => c).ToList();
return !w1.Where((t, i) => t != w2[i]).Any();
}
Which create two lists ordered with the words chars, then compare both.
More readable equivalent:
private static bool areAnagrams(string word1, string word2)
{
List<char> w1 = word1.OrderBy(c => c).ToList();
List<char> w2 = word2.OrderBy(c => c).ToList();
if (w1.Count != w2.Count)
return false;
for (int i = 0; i < w1.Count; i++)
{
if (w1[i] != w2[i])
return false;
}
return true;
}
I fixed the problem,I just modified the if statement which checks if they're anagram or not:
for (int i = 0; i < list1.Count; i++)
{
if (list2.Contains(list1[i]))
{
list1.Remove(i);
// list2.Remove(list2.IndexOf(list1[i]));
i--;
counter++;
}
Thanks all of you for your helps :)
Your answers are:
int[] sayilar1 = new int[150];
int[] sayilar2 = new int[150];
public Form1()
{
InitializeComponent();
}
private void Form1_Load(object sender, EventArgs e)
{
var rand = new Random();
for (int i = 0; i < sayilar1.Length; i++)
{
sayilar1[i] = rand.Next();
sayilar2[i] = rand.Next();
lvNumbers.Items.Add(sayilar1[i].ToString());
lvNumbers.Items.Add(sayilar2[i].ToString());
}
}
private void btnShuffle_Click(object sender, EventArgs e)
{
int[]newArray=BubbleSort();
for (int i = 0; i < newArray.Count(); i++)
{
lvSorted.Items.Add(newArray[i].ToString());
}
}
private int[] BubbleSort()
{
int temp = 0;
int[] newArray = new int[300];
for (int i = 0; i < 300; i++)
{
if (i < 150)
{
newArray[i] = sayilar1[i];
}
if (i >= 150)
newArray[i] = sayilar2[i - 150];
}
for (int i = 0; i < newArray.Length; i++)
{
for (int sort = 0; sort < newArray.Length - 1; sort++)
{
if (newArray[sort] > newArray[sort + 1])
{
temp = newArray[sort + 1];
newArray[sort + 1] = newArray[sort];
newArray[sort] = temp;
}
}
}
return newArray;
}
}
2.
private void btnTek_Click(object sender, EventArgs e)
{
lvFiltered.Items.Clear();
string[] sayilar = tbSayilar.Text.Split('\n');
int[] array = new int[sayilar.Length];
for (int i = 0; i < sayilar.Length; i++)
{
array[i] = int.Parse(sayilar[i]);
}
List<int> ayiklanmisSayilar = TekCiftAyir(array, "T");
for (int i = 0; i < ayiklanmisSayilar.Count; i++)
{
lvFiltered.Items.Add(ayiklanmisSayilar[i].ToString());
}
}
private void btnCift_Click(object sender, EventArgs e)
{
lvFiltered.Items.Clear();
string[] sayilar = tbSayilar.Text.Split('\n');
int[] array = new int[sayilar.Length];
for (int i = 0; i < sayilar.Length; i++)
{
array[i] = int.Parse(sayilar[i]);
}
List<int> ayiklanmisSayilar = TekCiftAyir(array, "C");
for (int i = 0; i < ayiklanmisSayilar.Count; i++)
{
lvFiltered.Items.Add(ayiklanmisSayilar[i].ToString());
}
}
private List<int> TekCiftAyir(int[] array, string TC)
{
List<int> ayiklanmisSayilar = new List<int>();
if (TC == "T")
{
for (int i = 0; i < array.Length; i++)
{
if (array[i] % 2 == 1)
{
ayiklanmisSayilar.Add(array[i]);
}
}
}
if (TC == "C")
{
for (int i = 0; i < array.Length; i++)
{
if (array[i] % 2 == 0)
{
ayiklanmisSayilar.Add(array[i]);
}
}
}
return ayiklanmisSayilar;
}
}
Related
I am a total newbie to programming and i have been following some tutorials on array related to housie ticket generator.The point where I am stuck is that, I have to check each rows and each rows of the 3x9 matrix should not have more the two empty cells or it cannot have more then two cells filled next to each other.I am putting random numbers on the arrays and trying to validate the rules but,the program crashes. Can someone please give me an idea.?
This is what i've tried.
for(int columnIndex=0;columnIndex<=6;columnIndex++)
{
if(game[i,columnIndex+2]!=0)
{
return -1;
}
}
And this is the whole code
using System;
namespace HelloWorld
{
class Program
{
public static void Main (String[] args)
{
for(int times=0;times<2;times++)
{
startGame();
Console.WriteLine("******************************************************************");
}
}
private static void startGame()
{
int[,] game = new int[3, 9];
int occupancyLimit = 15;
while (occupancyLimit > 0)
{
int i = getRandomNumber(3);
int j = getRandomNumber(9);
//Console.Write(i);
//Console.Write(j);
// Console.Write(game[i,j]+" ");
int data = validateAndReturnNumber(i, j, game);
if (data>0)
{
game[i, j] = data;
occupancyLimit--;
//Console.WriteLine(game[i,j]);
}
}
for (int i = 0; i < game.GetLength(0); i++)
{
for (int j = 0; j < game.GetLength(1); j++)
{
Console.Write(game[i,j] + "\t");
}
Console.WriteLine();
}
}
private static int validateAndReturnNumber(int i, int j, int[,] game)
{
//do not override existing elements in array
if (game[i,j] != 0)
{
return -1;
}
//column cannot have more then two elements
int columncounter = 0;
for(int c=0;c<3;c++)
{
if(game[c,j]!=0)
{
columncounter++;
}
}
if(columncounter>=2)
{
return -1;
}
/*
//rows cannot have more then two cells filled in and
//rows cannot have more then two empty cells
for(int columnIndex=0;columnIndex<=6;columnIndex++)
{
if(game[i,columnIndex+2]!=0)
{
return -1;
}
}
*/
// rows cannot have more then 5 elements
int rowcounter = 0;
for(int r=0;r<9;r++)
{
if(game[i,r]!=0)
{
rowcounter++;
}
}
//Applying, rows cannot have more then 5 elements
if(rowcounter>=5)
{
return -1;
}
//return getRandomNumberForColumn(j);
int data = 0;
Boolean isValueSet = false;
do
{
data = getRandomNumberForColumn(j);
isValueSet = isValueExistsInCol(game, i, j, data);
} while (isValueSet);
return data;
}
private static bool isValueExistsInCol(int[,] game, int i, int j, int data)
{
Boolean status = false;
for(int k=0;k<3;k++)
{
if(game[k,j]==data)
{
status = true;
break;
}
}
return status;
}
private static int getRandomNumberForColumn(int high)
{
if(high==0)
{
high = 10;
}
else
{
high=(high + 1) * 10;
}
int low = high - 9;
Random random = new Random();
return random.Next(high-low)+low;
}
private static int getRandomNumber(int max)
{
Random random = new Random();
int num=random.Next(max);
return (num);
}
}
}
Why your for loop does not work:
for (int columnIndex = 0; columnIndex <= 6; columnIndex++)
{
if (game[i, columnIndex + 2] != 0)
{
return -1;
}
}
This loop does not take j into account. It is testing for previous numbers added, as soon as one previous number fails this test, it will fail indefinitely. This creates an infinite loop. This loop also fails if a number is placed in any position past 1, while it needs to fill 5 positions to succeed. This is mathematically impossible.
This:
'should not have more the two empty cells or it cannot have more then two cells' is also mathematically impossible. a row of 9 cannot have less than 2 full and less than 2 empty at the same time.
I think you are after 2 empty or full consecutively in a row. For that testing for two empty in a row cannot be achieved as it starts empty, and you are testing it before you fill it. Fortunately this is a redundant test that will always be true based on all of the other test cases.
No more than 2 full in a row is possible, but can also lead to impossible scenarios. I have added a check that resets the scenario if it has not found the solution after 1000 guesses.
using System;
namespace HelloWorld
{
class Program
{
public static void Main(String[] args)
{
for (int times = 0; times < 2; times++)
{
startGame();
// Console.WriteLine("******************************************************************");
}
}
private static void startGame()
{
int iCount = 0;
int[,] game = new int[3, 9];
int occupancyLimit = 15;
while (occupancyLimit > 0)
{
int i = getRandomNumber(3);
int j = getRandomNumber(9);
//Console.Write(i);
//Console.Write(j);
// Console.Write(game[i,j]+" ");
int data = validateAndReturnNumber(i, j, game);
if (data > 0)
{
game[i, j] = data;
occupancyLimit--;
//Console.WriteLine(game[i,j]);
}
else
{
iCount++;
//Console.WriteLine(iCount);
//printGame(game);
// If X many fails, retry
if(iCount > 1000)
{
iCount = 0;
game = new int[3, 9];
occupancyLimit = 15;
}
}
// If you want to check for zeros you would need to do it here. And use while(true) above
/*
if( //Check for zeros)
{
break; // Ends While loop
}
else
{
// Reset and try again
iCount = 0;
game = new int[3, 9];
occupancyLimit = 15;
}
*/
}
printGame(game);
}
private static void printGame(int[,] game)
{
for (int i = 0; i < game.GetLength(0); i++)
{
for (int j = 0; j < game.GetLength(1); j++)
{
Console.Write(game[i, j] + "\t");
}
Console.WriteLine();
}
Console.WriteLine("******************************************************************");
}
private static int validateAndReturnNumber(int i, int j, int[,] game)
{
//do not override existing elements in array
if (game[i, j] != 0)
{
return -1;
}
//column cannot have more then two elements
int columncounter = 0;
for (int c = 0; c < 3; c++)
{
if (game[c, j] != 0)
{
columncounter++;
}
}
if (columncounter >= 2)
{
return -1;
}
if(
(j != 0 && j != 1 && game[i, j - 2] != 0 && game[i, j - 1] != 0) || // 12X
(j != 0 && j != 8 && game[i, j - 1] != 0 && game[i, j + 1] != 0) || // 1X3
(j != 7 && j != 8 && game[i, j + 1] != 0 && game[i, j + 2] != 0) // X23
)
{
return -1;
}
//for (int columnIndex = 0; columnIndex <= 6; columnIndex++)
//{
// if (game[i, columnIndex + 2] != 0)
// {
// return -1;
// }
//}
// rows cannot have more then 5 elements
int rowcounter = 0;
for (int r = 0; r < 9; r++)
{
if (game[i, r] != 0)
{
rowcounter++;
}
}
//Applying, rows cannot have more then 5 elements
if (rowcounter >= 5)
{
return -1;
}
//return getRandomNumberForColumn(j);
int data = 0;
Boolean isValueSet = false;
do
{
data = getRandomNumberForColumn(j);
isValueSet = isValueExistsInCol(game, i, j, data);
} while (isValueSet);
return data;
}
private static bool isValueExistsInCol(int[,] game, int i, int j, int data)
{
Boolean status = false;
for (int k = 0; k < 3; k++)
{
if (game[k, j] == data)
{
status = true;
break;
}
}
return status;
}
private static int getRandomNumberForColumn(int high)
{
if (high == 0)
{
high = 10;
}
else
{
high = (high + 1) * 10;
}
int low = high - 9;
Random random = new Random();
return random.Next(high - low) + low;
}
private static int getRandomNumber(int max)
{
Random random = new Random();
int num = random.Next(max);
return (num);
}
}
}
Cheers!
I'm trying to compile the below code: (normally get and set operation)
please assist with reviewing the insertion sort function, all the rest compiling perfectly.
The return value comparing 2 cells only (and it's correct).
any idea what can cause that?
private static void Main()
{
IArray<int?> arr = Read();
Console.WriteLine(arr);
SelectionSort(arr);
Console.WriteLine(arr);
if (arr.Length >= 2)
{
arr.Set(arr.Length - 2, null);
Console.WriteLine(arr);
}
if (arr.Length >= 1)
{
arr.Set(arr.Length - 1, null);
Console.WriteLine(arr);
}
SelectionSort(arr);
Console.WriteLine(arr);
Console.WriteLine("(" + arr.Get(100) + ")");
Console.WriteLine("insertion sort");
int n = arr.Length;
Insertionsort(arr, n);
Console.WriteLine(arr);
//// throw exception
//_ = new DynArr<int>();
}
private static IArray<int?> Read()
{
var arr = new DynArr<int?>();
Console.Write("Enter size >> ");
var size = int.Parse(Console.ReadLine().Trim());
for (var i = 0; i < size; ++i)
{
Console.Write("Enter [" + i + "] >> ");
arr.Set(i, int.Parse(Console.ReadLine().Trim()));
}
return arr;
}
}
private static void Insertionsort(IArray<int?> arr, int n)
{
for (int i = 1; i < n; i++)
{
var j = i - 1;
voidcompare(arr, i, j);
}
}
private static void voidcompare(IArray<int?> arr, int i, int j)
{
var c = arr.Get(i);
while (j >= 0 && arr.Get(j) > c)
{
arr.Set(j + 1, c);
}
}
}
}
Your Sort alg. isn't corect. See hier how it's working - Insertion Sort. Bellow i provide you a possible implementation.
public class Program
{
static void Main()
{
var collection = new List<int?> { 25, 71, 43, -1, 15, 0, 38 };
DoInsertionSort(collection, collection.Count);
Console.WriteLine(string.Join(Environment.NewLine, collection));
}
static void DoInsertionSort(IList<int?> collection, int length)
{
if (collection is null || collection.Count == 0 || length <= 0 || length > collection.Count)
{
return;
}
var previous = default(int?);
for (int index = 0; index < length; index++)
{
var current = collection.Get(index);
if (current < previous)
{
SwapUpToStart(collection, current, index);
}
previous = collection.Get(index);
}
}
private static void SwapUpToStart(IList<int?> collection, int? current, int currentIndex)
{
for (int index = currentIndex - 1; index >= 0; index--)
{
var previous = collection.Get(index);
if (current >= previous)
{
break;
}
collection.Swap(index, current, previous);
}
}
}
public static class YourIArray_T_Implementation
{
public static int? Get(this IList<int?> collection, int index)
{
return collection[index];
}
public static void Swap(this IList<int?> collection, int index, int? current, int? previous)
{
collection[index] = current;
collection[index + 1] = previous;
}
}
I have to find subtext in text without using builtin function of string.
public static void Main(string[] args)
{
string subtext = "polly";
string text = "polly put the katle on,polly put the katle on,polly put the katle on,we all have tea";
int i, j, found;
int strLen, wordLen;
strLen = text.Length;
wordLen = subtext.Length;
for (i = 0; i < strLen - wordLen; i++)
{
found = 1;
for (j = 0; j < wordLen; j++)
{
if (text[i + j] != subtext[j])
{
found = 0;
break;
}
}
if (found == 1)
{
Console.WriteLine(" found at index:", subtext, i);
Console.ReadLine();
}
}
}
I am not sure how long you would like to search, your current code seems to find all indexes (or at least that seems to be the intent)
Some things you could change however is instead of always starting the loop, you could validate the if the char at position i matches the first char of the subtext, and if not continue.
When you want to write the data to the console, don't forget to add the spaceholders for your arguments, like:
Console.WriteLine("found {0} at index: {1}", subtext, i);
For the rest, I guess your current implementation is okay, but you could add some validations, like ensuring that both texts are available, and if subtext is longer than the text, simply return -1 directly.
For a simple find of first index, I wrote this one up, it still looks pretty similar to yours
private static int FindIn( string text, string sub ) {
if (string.IsNullOrWhiteSpace( text ) || string.IsNullOrWhiteSpace( sub ) ) {
return string.IsNullOrWhiteSpace( sub ) ? 0 : -1;
}
if (text.Length < sub.Length) {
return -1;
}
for (int i = 0; i < text.Length - sub.Length; i++) {
if (text[i] != sub[0]) {
continue;
}
var matched = true;
for (int j = 1; j < sub.Length && i + j < text.Length; j++) {
if (text[i+j] != sub[j]) {
matched = false;
break;
}
}
if (matched) {
return i;
}
}
return -1;
}
Which you can play around with here
There are a lot of pattern-matching algorithms in this book, i will leave here c# implementation of Knuth-Morris-Pratt algorithm.
static int[] GetPrefix(string s)
{
int[] result = new int[s.Length];
result[0] = 0;
int index = 0;
for (int i = 1; i < s.Length; i++)
{
while (index >= 0 && s[index] != s[i]) { index--; }
index++;
result[i] = index;
}
return result;
}
static int FindSubstring(string pattern, string text)
{
int res = -1;
int[] pf = GetPrefix(pattern);
int index = 0;
for (int i = 0; i < text.Length; i++)
{
while (index > 0 && pattern[index] != text[i]) { index = pf[index - 1]; }
if (pattern[index] == text[i]) index++;
if (index == pattern.Length)
{
return res = i - index + 1;
}
}
return res;
}
If you are looking for all occurance of the subtect in the text you can use the following code:
public static void Main(string[] args)
{
string subtext = "polly";
string text = "polly put the katle on,polly put the katle on,polly put the katle on,we all have tea";
int index = 0;
int startPosition = 0;
bool found = false;
while (index < text.Length - 1)
{
if (subtext[0] == text[index])
{
startPosition = index;
index++;
for (int j = 1; j <= subtext.Length - 1; j++)
{
if (subtext[j] != text[index])
{
found = false;
break;
}
else
{
found = true;
}
index++;
}
}
if (found)
{
Console.WriteLine("{0} found at index: {1}", subtext, startPosition);
found = false;
}
index++;
}
Console.ReadLine();
}
If you are looking only for the first occurance add break in the "if (found)" condition
Ok so I finished my code n queens genetics in c# but I keep getting these compiler errors even though I changed the code several times
using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using System.Threading.Tasks;
namespace NQueen1
{
class Program
{
private const int sSize = 75; // Population size at start.
private const int mTest = 1000; // Arbitrary number of test cycles.
private const double pMating = 0.7; // Probability of two chromosomes mating. Range: 0.0 < MATING_PROBABILITY < 1.0
private const double rMutation = 0.001; // Mutation Rate. Range: 0.0 < MUTATION_RATE < 1.0
private const int minS = 10; // Minimum parents allowed for selection.
private const int MaxS = 50; // Maximum parents allowed for selection. Range: MIN_SELECT < MAX_SELECT < START_SIZE
private const int offSpring = 20; // New offspring created per generation. Range: 0 < OFFSPRING_PER_GENERATION < MAX_SELECT.
private const int minRandom = 8; // For randomizing starting chromosomes
private const int maxShuffles = 20;
private const int maxPBC = 4; // Maximum Position-Based Crossover points. Range: 0 < PBC_MAX < 8 (> 8 isn't good).
private const int maxLength = 10; // chess board width.
private static int epoch = 0;
private static int childCount = 0;
private static int nextMutation = 0; // For scheduling mutations.
private static int mutations = 0;
private static List<Chromosome> population = new List<Chromosome>();
private static void algorithm()
{
int popSize = 0;
Chromosome thisChromo = null;
bool done = false;
initializeChromosomes();
mutations = 0;
nextMutation = getRandomNumber(0, (int)Math.Round(1.0 / rMutation));
while (!done)
{
popSize = population.Count;
for (int i = 0; i < popSize; i++)
{
thisChromo = population[i];
if ((thisChromo.conflicts() == 0) || epoch == mTest)
{
done = true;
}
}
getFitness();
rouletteSelection();
mating();
prepNextEpoch();
epoch++;
// This is here simply to show the runtime status.
Console.WriteLine("Epoch: " + epoch);
}
Console.WriteLine("done.");
if (epoch != rMutation)
{
popSize = population.Count;
for (int i = 0; i < popSize; i++)
{
thisChromo = population[i];
if (thisChromo.conflicts() == 0)
{
printSolution(thisChromo);
}
}
}
Console.WriteLine("Completed " + epoch + " epochs.");
Console.WriteLine("Encountered " + mutations + " mutations in " + childCount + " offspring.");
return;
}
private static void getFitness()
{
// Lowest errors = 100%, Highest errors = 0%
int popSize = population.Count;
Chromosome thisChromo = null;
double bestScore = 0;
double worstScore = 0;
// The worst score would be the one with the highest energy, best would be lowest.
worstScore = population[maximum()].conflicts();
// Convert to a weighted percentage.
bestScore = worstScore - population[minimum()].conflicts();
for (int i = 0; i < popSize; i++)
{
thisChromo = population[i];
thisChromo.fitness((worstScore - thisChromo.conflicts()) * 100.0 / bestScore);
}
return;
}
private static void rouletteSelection()
{
int j = 0;
int popSize = population.Count;
double genT = 0.0;
double selT = 0.0;
int maximumToSelect = getRandomNumber(minS, MaxS);
double rouletteSpin = 0.0;
Chromosome thisChromo = null;
Chromosome thatChromo = null;
bool done = false;
for (int i = 0; i < popSize; i++)
{
thisChromo = population[i];
genT += thisChromo.fitness();
}
genT *= 0.01;
for (int i = 0; i < popSize; i++)
{
thisChromo = population[i];
thisChromo.selectionProbability(thisChromo.fitness() / genT);
}
for (int i = 0; i < maximumToSelect; i++)
{
rouletteSpin = getRandomNumber(0, 99);
j = 0;
selT = 0;
done = false;
while (!done)
{
thisChromo = population[j];
selT += thisChromo.selectionProbability();
if (selT >= rouletteSpin)
{
if (j == 0)
{
thatChromo = population[j];
}
else if (j >= popSize - 1)
{
thatChromo = population[popSize - 1];
}
else
{
thatChromo = population[j - 1];
}
thatChromo.selected(true);
done = true;
}
else
{
j++;
}
}
}
return;
}
// This is where you can choose between options:
// To choose between crossover options, uncomment one of:
// partiallyMappedCrossover(),
// positionBasedCrossover(), while keeping the other two commented out.
private static void mating()
{
int getRand = 0;
int parentA = 0;
int parentB = 0;
int newIndex1 = 0;
int newIndex2 = 0;
Chromosome newChromo1 = null;
Chromosome newChromo2 = null;
for (int i = 0; i < offSpring; i++)
{
parentA = chooseParent();
// Test probability of mating.
getRand = getRandomNumber(0, 100);
if (getRand <= pMating * 100)
{
parentB = chooseParent(parentA);
newChromo1 = new Chromosome();
newChromo2 = new Chromosome();
population.Add(newChromo1);
newIndex1 = population.IndexOf(newChromo1);
population.Add(newChromo2);
newIndex2 = population.IndexOf(newChromo2);
// Choose either, or both of these:
partialCrossover(parentA, parentB, newIndex1, newIndex2);
//positionBasedCrossover(parentA, parentB, newIndex1, newIndex2);
if (childCount - 1 == nextMutation)
{
exchangeMutation(newIndex1, 1);
}
else if (childCount == nextMutation)
{
exchangeMutation(newIndex2, 1);
}
population[newIndex1].computeConflicts();
population[newIndex2].computeConflicts();
childCount += 2;
// Schedule next mutation.
if (childCount % (int)Math.Round(1.0 / rMutation) == 0)
{
nextMutation = childCount + getRandomNumber(0, (int)Math.Round(1.0 / rMutation));
}
}
} // i
return;
}
private static void partialCrossover(int chromA, int chromB, int child1, int child2)
{
int j = 0;
int item1 = 0;
int item2 = 0;
int pos1 = 0;
int pos2 = 0;
Chromosome thisChromo = population[chromA];
Chromosome thatChromo = population[chromB];
Chromosome newChromo1 = population[child1];
Chromosome newChromo2 = population[child2];
int crossPoint1 = getRandomNumber(0, maxLength - 1);
int crossPoint2 = getExclusiveRandomNumber(maxLength - 1, crossPoint1);
if (crossPoint2 < crossPoint1)
{
j = crossPoint1;
crossPoint1 = crossPoint2;
crossPoint2 = j;
}
// Copy Parent genes to offspring.
for (int i = 0; i < maxLength; i++)
{
newChromo1.data(i, thisChromo.data(i));
newChromo2.data(i, thatChromo.data(i));
}
for (int i = crossPoint1; i <= crossPoint2; i++)
{
// Get the two items to swap.
item1 = thisChromo.data(i);
item2 = thatChromo.data(i);
// Get the items// positions in the offspring.
for (j = 0; j < maxLength; j++)
{
if (newChromo1.data(j) == item1)
{
pos1 = j;
}
else if (newChromo1.data(j) == item2)
{
pos2 = j;
}
} // j
// Swap them.
if (item1 != item2)
{
newChromo1.data(pos1, item2);
newChromo1.data(pos2, item1);
}
// Get the items// positions in the offspring.
for (j = 0; j < maxLength; j++)
{
if (newChromo2.data(j) == item2)
{
pos1 = j;
}
else if (newChromo2.data(j) == item1)
{
pos2 = j;
}
} // j
// Swap them.
if (item1 != item2)
{
newChromo2.data(pos1, item1);
newChromo2.data(pos2, item2);
}
} // i
return;
}
private static void positionCrossover(int chromA, int chromB, int child1, int child2)
{
int k = 0;
int numPoints = 0;
int[] tempArray1 = new int[maxLength];
int[] tempArray2 = new int[maxLength];
bool matchFound = false;
Chromosome thisChromo = population[chromA];
Chromosome thatChromo = population[chromB];
Chromosome newChromo1 = population[child1];
Chromosome newChromo2 = population[child2];
// Choose and sort the crosspoints.
numPoints = getRandomNumber(0, maxPBC);
int[] crossPoints = new int[numPoints];
int negativeNancy = -1;
for (int i = 0; i < numPoints; i++)
{
crossPoints[i] = getRandomNumber(0, maxLength - negativeNancy, crossPoints);
} // i
// Get non-chosens from parent 2
k = 0;
for (int i = 0; i < maxLength; i++)
{
matchFound = false;
for (int j = 0; j < numPoints; j++)
{
if (thatChromo.data(i) == thisChromo.data(crossPoints[j]))
{
matchFound = true;
}
} // j
if (matchFound == false)
{
tempArray1[k] = thatChromo.data(i);
k++;
}
} // i
// Insert chosens into child 1.
for (int i = 0; i < numPoints; i++)
{
newChromo1.data(crossPoints[i], thisChromo.data(crossPoints[i]));
}
// Fill in non-chosens to child 1.
k = 0;
for (int i = 0; i < maxLength; i++)
{
matchFound = false;
for (int j = 0; j < numPoints; j++)
{
if (i == crossPoints[j])
{
matchFound = true;
}
} // j
if (matchFound == false)
{
newChromo1.data(i, tempArray1[k]);
k++;
}
} // i
// Get non-chosens from parent 1
k = 0;
for (int i = 0; i < maxLength; i++)
{
matchFound = false;
for (int j = 0; j < numPoints; j++)
{
if (thisChromo.data(i) == thatChromo.data(crossPoints[j]))
{
matchFound = true;
}
} // j
if (matchFound == false)
{
tempArray2[k] = thisChromo.data(i);
k++;
}
} // i
// Insert chosens into child 2.
for (int i = 0; i < numPoints; i++)
{
newChromo2.data(crossPoints[i], thatChromo.data(crossPoints[i]));
}
// Fill in non-chosens to child 2.
k = 0;
for (int i = 0; i < maxLength; i++)
{
matchFound = false;
for (int j = 0; j < numPoints; j++)
{
if (i == crossPoints[j])
{
matchFound = true;
}
} // j
if (matchFound == false)
{
newChromo2.data(i, tempArray2[k]);
k++;
}
} // i
return;
}
private static void exchangeMutation(int index, int exchanges)
{
int i = 0;
int tempData = 0;
Chromosome thisChromo = null;
int gene1 = 0;
int gene2 = 0;
bool done = false;
thisChromo = population[index];
while (!done)
{
gene1 = getRandomNumber(0, maxLength - 1);
gene2 = getExclusiveRandomNumber(maxLength - 1, gene1);
// Exchange the chosen genes.
tempData = thisChromo.data(gene1);
thisChromo.data(gene1, thisChromo.data(gene2));
thisChromo.data(gene2, tempData);
if (i == exchanges)
{
done = true;
}
i++;
}
mutations++;
return;
}
private static int chooseParent()
{
// Overloaded function, see also "chooseparent(ByVal parentA As Integer)".
int parent = 0;
Chromosome thisChromo = null;
bool done = false;
while (!done)
{
// Randomly choose an eligible parent.
parent = getRandomNumber(0, population.Count - 1);
thisChromo = population[parent];
if (thisChromo.selected() == true)
{
done = true;
}
}
return parent;
}
{
// Overloaded function, see also "chooseparent()".
int parent = 0;
Chromosome thisChromo = null;
bool done = false;
while (!done)
{
// Randomly choose an eligible parent.
parent = getRandomNumber(0, population.Count - 1);
if (parent != parentA)
{
thisChromo = population[parent];
if (thisChromo.selected() == true)
{
done = true;
}
}
}
return parent;
}
private static void prepNextEpoch()
{
int popSize = 0;
Chromosome thisChromo = null;
// Reset flags for selected individuals.
popSize = population.Count;
for (int i = 0; i < popSize; i++)
{
thisChromo = population[i];
thisChromo.selected(false);
}
return;
}
private static void printSolution(Chromosome bestSolution)
{
string[][] board = RectangularArrays.ReturnRectangularStringArray(maxLength, maxLength);
// Clear the board.
for (int x = 0; x < maxLength; x++)
{
for (int y = 0; y < maxLength; y++)
{
board[x][y] = "";
}
}
for (int x = 0; x < maxLength; x++)
{
board[x][bestSolution.data(x)] = "Q";
}
// Display the board.
Console.WriteLine("Board:");
for (int y = 0; y < maxLength; y++)
{
for (int x = 0; x < maxLength; x++)
{
if (string.ReferenceEquals(board[x][y], "Q"))
{
Console.Write("Q ");
}
else
{
Console.Write(". ");
}
}
Console.Write("\n");
}
return;
}
private static int getRandomNumber(int low, int high)
{
return (int)Math.Round((high - low) * (new Random()).NextDouble() + low);
}
private static int getExclusiveRandomNumber(int high, int except)
{
bool done = false;
int getRand = 0;
while (!done)
{
getRand = (new Random()).Next(high);
if (getRand != except)
{
done = true;
}
}
return getRand;
}
private static int getRandomNumber(int low, int high, int[] except)
{
bool done = false;
int getRand = 0;
if (high != low)
{
while (!done)
{
done = true;
getRand = (int)Math.Round((high - low) * (new Random()).NextDouble() + low);
for (int i = 0; i < except.Length; i++) //UBound(except)
{
if (getRand == except[i])
{
done = false;
}
} // i
}
return getRand;
}
else
{
return high; // or low (it doesn't matter).
}
}
private static int minimum()
{
// Returns an array index.
int popSize = 0;
Chromosome thisChromo = null;
Chromosome thatChromo = null;
int winner = 0;
bool foundNewWinner = false;
bool done = false;
while (!done)
{
foundNewWinner = false;
popSize = population.Count;
for (int i = 0; i < popSize; i++)
{
if (i != winner)
{ // Avoid self-comparison.
thisChromo = population[i];
thatChromo = population[winner];
if (thisChromo.conflicts() < thatChromo.conflicts())
{
winner = i;
foundNewWinner = true;
}
}
}
if (foundNewWinner == false)
{
done = true;
}
}
return winner;
}
private static int maximum()
{
// Returns an array index.
int popSize = 0;
Chromosome thisChromo = null;
Chromosome thatChromo = null;
int winner = 0;
bool foundNewWinner = false;
bool done = false;
while (!done)
{
foundNewWinner = false;
popSize = population.Count;
for (int i = 0; i < popSize; i++)
{
if (i != winner)
{ // Avoid self-comparison.
thisChromo = population[i];
thatChromo = population[winner];
if (thisChromo.conflicts() > thatChromo.conflicts())
{
winner = i;
foundNewWinner = true;
}
}
}
if (foundNewWinner == false)
{
done = true;
}
}
return winner;
}
private static void initializeChromosomes()
{
int shuffles = 0;
Chromosome newChromo = null;
int chromoIndex = 0;
for (int i = 0; i < sSize; i++)
{
newChromo = new Chromosome();
population.Add(newChromo);
chromoIndex = population.IndexOf(newChromo);
// Randomly choose the number of shuffles to perform.
shuffles = getRandomNumber(minRandom, maxShuffles);
exchangeMutation(chromoIndex, shuffles);
population[chromoIndex].computeConflicts();
}
return;
}
private class Chromosome
{
internal int[] mData = new int[maxLength];
internal double mFitness = 0.0;
internal bool mSelected = false;
internal double mSelectionProbability = 0.0;
internal int mConflicts = 0;
public Chromosome()
{
for (int i = 0; i < maxLength; i++)
{
this.mData[i] = i;
}
return;
}
public virtual void computeConflicts()
{
int x = 0;
int y = 0;
int tempx = 0;
int tempy = 0;
//string[][] board = new string[MAX_LENGTH][MAX_LENGTH];
string[][] board = RectangularArrays.ReturnRectangularStringArray(maxLength, maxLength);
int conflicts = 0;
int[] dx = new int[] { -1, 1, -1, 1 };
int[] dy = new int[] { -1, 1, 1, -1 };
bool done = false;
// Clear the board.
for (int i = 0; i < maxLength; i++)
{
for (int j = 0; j < maxLength; j++)
{
board[i][j] = "";
}
}
for (int i = 0; i < maxLength; i++)
{
board[i][this.mData[i]] = "Q";
}
// Walk through each of the Queens and compute the number of conflicts.
for (int i = 0; i < maxLength; i++)
{
x = i;
y = this.mData[i];
// Check diagonals.
for (int j = 0; j <= 3; j++)
{
tempx = x;
tempy = y;
done = false;
while (!done)
{
tempx += dx[j];
tempy += dy[j];
if ((tempx < 0 || tempx >= maxLength) || (tempy < 0 || tempy >= maxLength))
{
done = true;
}
else
{
if (board[tempx][tempy].ToString().ToUpper().Equals("Q"))// ignore the case of 2 strings
{
conflicts++;
}
}
}
}
}
this.mConflicts = conflicts;
}
public virtual void conflicts(int value)
{
this.mConflicts = value;
return;
}
public virtual int conflicts()
{
return this.mConflicts;
}
public virtual double selectionProbability()
{
return mSelectionProbability;
}
public virtual void selectionProbability(double SelProb)
{
mSelectionProbability = SelProb;
return;
}
public virtual bool selected()
{
return mSelected;
}
public virtual void selected(bool sValue)
{
mSelected = sValue;
return;
}
public virtual double fitness()
{
return mFitness;
}
public virtual void fitness(double score)
{
mFitness = score;
return;
}
public virtual int data(int index)
{
return mData[index];
}
public virtual void data(int index, int value)
{
mData[index] = value;
return;
}
} // Chromosome
static void Main(string[] args)
{
algorithm();
return;
}
}
}
This is the second code here:
namespace NQueen1
{
internal static class RectangularArrays
{
internal static string[][] ReturnRectangularStringArray(int size1, int size2)
{
string[][] newArray = new string[size1][];
for (int array1 = 0; array1 < size1; array1++)
{
newArray[array1] = new string[size2];
}
return newArray;
}
}
}
THe Error:
Unhandled Exception: System.ArgumentOutOfRangeException: Index was out of range. Must be non-negative and less than the size of the collection.
Parameter name: index
at System.ThrowHelper.ThrowArgumentOutOfRangeException(ExceptionArgument argument, ExceptionResource resource)
at System.Collections.Generic.List`1.get_Item(Int32 index)
at NQueen1.Program.rouletteSelection() in C:\Users\Inspiron\Documents\coid\NQueen1\NQueen1\Program.cs:line 143
at NQueen1.Program.algorithm() in C:\Users\Inspiron\Documents\coid\NQueen1\NQueen1\Program.cs:line 56
at NQueen1.Program.Main(String[] args) in C:\Users\Inspiron\Documents\coid\NQueen1\NQueen1\Program.cs:line 841
I have no clue why its throwing off these errors I tried about almost everything I could think of to fix it
This is just a random guess.
My Spidey Senses tells me thisChromo = population[j] is probably overrunning the size of array, i.e. its in a while loop with j++ and there is no real bounds checking
private static void rouletteSelection()
{
...
for (int i = 0; i < maximumToSelect; i++)
{
...
while (!done)
{
thisChromo = population[j];
...
j++;
If this is the problem, I'd consider the possibility that j will be larger than population.Length and therefore breaking out of the loop; using an if statement; or just refactoring this logic
Tips for your future questions
If you have a runtime error, show us the line of code it has the error on
Pasting code is vital, however pasting too much is annoying and hard to read
If you paste code, at least try to format it
Learn to use the debugger and breakpoints (see: How to use the Debugger, Using Breakpoints).
This program calculates the expected number of toin cosses until a given sequence will appear. The formula sums powers of two, where powers are those k for which the first k elements of the sequence match the last k elements, in order.
My question is why, when I test it with two different sequences, it only returns one result twice. I assume that it is doing exactly what it looks like and overwriting test1 with test4 when test4 is instanciated, but this code looks to me to be similar to code from smaller exercises that did not have this overwriting behaviour.
This is my second programming course, and my first in C#, neither has been in my mother tongue, so I might be a bit slow with some of the concepts.
I suspect this has to do with one of the lines with public static... (I am not sure how to refer to them) or maybe a protection level. The expectation for test1 should be 38 (2 + 2^2 + 2^5).
using System;
namespace CSProject
{
class Program
{
static void Main(string[] args)
{
Console.WriteLine("Expectation tests");
PlayerSequence test1 = new PlayerSequence("bc00100");
PlayerSequence test4 = new PlayerSequence("101101");
Console.WriteLine("Expectation of test1 bc00100");
Console.WriteLine (test1.Expectation ());
Console.WriteLine("Expectation of test4 101101");
Console.WriteLine(test4.Expectation());
}
}
class PlayerSequence
{
//ATTRIBUTES
private static bool[] sequence;
//CONSTRUCTORS
public PlayerSequence()
{
}
public PlayerSequence(string sequence_String)//Seems to work!!
{
char[] sequence_array = sequence_String.ToCharArray();
int inputLength = sequence_array.Length;
int sequence_length = 0;
for( int i = 0; i < inputLength; i++) {
if (sequence_array[i] == '1' || sequence_array[i] == '0') {
sequence_length++;
}
}
sequence = new bool[sequence_length];///KEYItem
int input_index_adjustment = 0;
for (int i = 0; i < inputLength; i++) {
int sVal;
if (!Int32.TryParse(sequence_String[i].ToString(), out sVal))
{
input_index_adjustment++;
continue;
}
if (sVal == (Int32)1)
PlayerSequence.sequence[i - input_index_adjustment] = true;
if (sVal == (Int32)0)
PlayerSequence.sequence[i - input_index_adjustment] = false;
if(sVal != 1 && sVal != 0)
input_index_adjustment++;
}
}
public override string ToString()//Works
{
string retString;
retString = "";
for (int i = 0; i < sequence.Length;i++) {
if (sequence[i] == true) retString = retString + "T ";
else retString = retString + "H ";
}
return retString;
}
public ulong Expectation(){
ulong espTA = 0;
for (int kexp = 0; kexp < /*PlayerSequence.*/sequence.Length; kesp++)
{
if(SeqCheck(sequence,kesp+1))
expTA = expTA + (ulong)Math.Pow(2, kexp+1);
}
return espTA;
}//end Expectation
public static bool SeqCheck(bool[] toCheck, int k){
//Test of required property for each power of 2 here k
int a = toCheck.Length ;
bool seqgood = false;
bool[] checkStart = new bool[k];
bool[] checkEnd = new bool[k];
for (int i = 0; i < k; i++) {//loop sets up subarrays to compare
checkStart[i] = toCheck[i];
checkEnd[i] = toCheck[a - k + i];
}
for (int i = 0; i < k; i++){//loop does comparison
if(checkStart[i] != checkEnd[i])
{
seqgood = false;
break;
}
seqgood = true;
}
return seqgood;
}//end SeqCheck
}//end PlayerSequence class
}//End this section of the namespace
It is your use of the static keyword for the local variable in your class. By doin so, you make the variable a part of the type (PlayerSequence) and not the instance of PlayerSequence (test1, test4). Below worked on my machine.
class PlayerSequence
{
//ATTRIBUTES
private bool[] sequence;
//CONSTRUCTORS
public PlayerSequence()
{
}
public PlayerSequence(string sequence_String)//Seems to work!!
{
char[] sequence_array = sequence_String.ToCharArray();
int inputLength = sequence_array.Length;
int sequence_length = 0;
for (int i = 0; i < inputLength; i++)
{
if (sequence_array[i] == '1' || sequence_array[i] == '0')
{
sequence_length++;
}
}
sequence = new bool[sequence_length];///KEYItem
int input_index_adjustment = 0;
for (int i = 0; i < inputLength; i++)
{
int sVal;
if (!Int32.TryParse(sequence_String[i].ToString(), out sVal))
{
input_index_adjustment++;
continue;
}
if (sVal == (Int32)1)
sequence[i - input_index_adjustment] = true;
if (sVal == (Int32)0)
sequence[i - input_index_adjustment] = false;
if (sVal != 1 && sVal != 0)
input_index_adjustment++;
}
}
public override string ToString()//Works
{
string retString;
retString = "";
for (int i = 0; i < sequence.Length; i++)
{
if (sequence[i] == true) retString = retString + "T ";
else retString = retString + "H ";
}
return retString;
}
public ulong Expectation()
{
ulong espTA = 0;
for (int kexp = 0; kexp < sequence.Length; kexp++)
{
if (SeqCheck(sequence, kexp + 1))
espTA = espTA + (ulong)Math.Pow(2, kexp + 1);
}
return espTA;
}//end Expectation
public bool SeqCheck(bool[] toCheck, int k)
{
//Test of required property for each power of 2 here k
int a = toCheck.Length;
bool seqgood = false;
bool[] checkStart = new bool[k];
bool[] checkEnd = new bool[k];
for (int i = 0; i < k; i++)
{//loop sets up subarrays to compare
checkStart[i] = toCheck[i];
checkEnd[i] = toCheck[a - k + i];
}
for (int i = 0; i < k; i++)
{//loop does comparison
if (checkStart[i] != checkEnd[i])
{
seqgood = false;
break;
}
seqgood = true;
}
return seqgood;
}//end SeqCheck
}