Searching sets of numbers in random numbers using binary search algorithm - c#

My Code below is not working, not giving me any output. It was working well when I asked users to enter set of numbers and find within. But when I tried to search within random numbers, it is not working at all. Can anyone help me figure out, what did I do wrong, because program build successfully. It just won't giving the correct output.
{
class program
{
public class BinarySearch
{
public static int Search(int[] list, int x, int lower, int upper)
{
if (lower == upper)
{
int middle = (lower + upper) / 2;
if (x == list[middle])
return middle;
else if (x > list[middle] )
return Search(list, x, lower, middle - 1);
else
return Search(list, x, middle + 1, upper);
}
return 0;
}
public static void Main(String[] args)
{
int key;
int index;
int low = 0;
int high = 1000;
int[] list = new int[1000];
Random RandomNumber = new Random();
for (int i = 0; i < 1000; i++)
{
list[i] = RandomNumber.Next(1, 1000);
}
foreach (int j in list)
{
Console.WriteLine("{0}", j);
}
Console.WriteLine("...................................................\n");
Console.WriteLine("\nEnter the number to be searched in the list.");
key = Convert.ToInt32(Console.ReadLine());
index = Search(list, key, low, high);
Console.WriteLine("...................................................\n");
if (index == 0)
Console.WriteLine("Key {0} not found", key);
else
Console.WriteLine("Key {0} found at index {1}", key, index);
}
}
}
}

You're not sorting the "list".
Binary search requires the list to be sorted by the same rules you're using < and > inside the binary search algorithm, otherwise it will not work.
So sort the numbers in the array and the binary search should work much better.
Note, I think you've reversed the partition statements inside the numbers. If x > list[middle], then you need to search the upper part, not the lower part. This alone will not explain or fix your problem though, first you need to sort the numbers.
Finally, know that 0 is a valid index into the array, which means that you won't be able to distinguish between "not found" and "found at index 0" with your code.
My advice: Find an existing implementation of binary search and copy that, or at least use it as a source for inspiration.

Related

In my class i have to creating a method to find multiple maximum numbers in an array C#

In my class i have to create a method that will find multiple maximum numbers within an array. the user will input how many maximum numbers they are wanting and then the code should display all those numbers. if i select 2 this code will show me the 2 maximum numbers but if im wanting more it just doesnt work. i was trying to search the array for the maximum number and then have it display the outcome and then change that element to 0 and than repeat the loop until it hits that number (userinput). im soo frustrated can someone help me please
public static int FindingMaxNum(int[] arr, int max)
{
int userinput;
Console.Write("Enter the number of maximum values: ");
userinput = Convert.ToInt32(Console.Read());
int i = 0;
int c = 0;
for (i = 0; i < arr.Length; i++)
{
if (arr[i] >= max)
{
max = arr[i];
c++;
while (c <= userinput)
{
Console.WriteLine(max);
arr[i] = 0;
break;
}
}
}
return -1;
}
If I understand correctly, you want to get some number of items from an array whose values are greater than all the others in the array.
If so, something like this modified version of your method may do the trick:
public static void WriteMaxNum(int[] arr)
{
if (arr == null)
{
Console.WriteLine("The array is null");
return;
}
if (arr.Length == 0)
{
Console.WriteLine("The array is empty");
return;
}
int count = arr.Length;
int numMaxValues;
// Get number of max values to return from user
do
{
Console.Write("Enter the number of maximum values (1 - {0}): ", count);
} while (!int.TryParse(Console.ReadLine(), out numMaxValues) ||
numMaxValues < 1 ||
numMaxValues > count);
// Output the max values
Console.Write("The {0} max values are: ", numMaxValues);
Console.WriteLine(string.Join(", ", arr.OrderByDescending(i => i).Take(numMaxValues)));
}
Usage
static void Main(string[] args)
{
var myArray = new[] { 1, 9, 4, 8, 2, 5, 0, 7, 6, 3 };
WriteMaxNum(myArray);
Console.Write("\nDone!\nPress any key to exit...");
Console.ReadKey();
}
Output
Simple solution with average complexity O(nlogn):
Sort the array first then print the last N nos.
int[] arr = new int[]{-5,-69,1250,24,-96,32578,11,124};
Array.Sort(arr);
int n=3;
for(int i=arr.Length-1;i>=0 && n>0 ;--i){
n--;
Console.WriteLine(arr[i]);
}
Now coming to your code, there are multiple problems. First there is no need to take 'max' as parameter in your function. Second you are looping only arr.Length times once. There should be nested loop, outer one of which has to run userInput times and inner on has to iterate over all the values. Third you should initialize to extracted value position to minimum value so that the method works for negative numbers too.
Refined code:
for(int i=0;i<userinput;++i){
int max = int.MinValue,pos=-1;
for(int j=0;j<arr.Length;++j){
if(max<arr[j]){
pos = j;
max = arr[j];
}
}
arr[pos] = int.MinValue;
Console.Write(max+",");
}

c# - Binary search algorithm random generated array items not working

I have implemented binary search algorithm in a console window application in C#. I am generating random values to the array and sorting them using Random() and Array.Sort() functions respectively.
The Problem - No matter what Key(item to be searched in the array) I give, the program is returning Key not found when the array items are generated using Random function
This does not happen if I enter the array elements manually using Console.ReadLine().
TLDR: Binary Search algorithm works fine when array items are entered manually, but does not work when array items are generated using Random function.
Can anyone point out what is the mistake I am doing?
My code - Random Generated array items.
namespace BSA
{
class Program
{
static void Main(string[] args)
{
var arr = new int[10];
Random rnd = new Random();
for (int i = 0; i < arr.Length; i++)
{
arr[i] = rnd.Next(1, 1000);
}
Array.Sort(arr);
for (int i = 0; i < arr.Length; i++)
{
Console.Write("{0}\n", i);
}
while (true)
{
Console.WriteLine("Enter the number to be searched in the array.");
var searchItem = Convert.ToInt32(Console.ReadLine());
var foundPos = Search(arr, searchItem);
if (foundPos > 0)
{
Console.WriteLine("Key {0} found at position {1}", searchItem, foundPos);
}
else
{
Console.WriteLine("Key {0} not found", searchItem);
}
}
}
public static int Search(int[] arr, int item)
{
var min = 0;
var N = arr.Length;
var max = N - 1;
int basicOperations = 0;
basicOperations++;
do
{
var mid = (min + max)/2;
if (arr[mid] == item)
return mid;
if (item < arr[mid])
max = mid - 1;
else
min = mid + 1;
basicOperations++;
} while (min <= max);
return basicOperations;
}
}
}
Please let me know if I am doing any silly mistake or I am committing a blunder in the above code. Any help would be really helpful.
Your search code works fine as far as I can see. However when you list the contents of the random array, you should write arr[i] rather than i to see what's in the array so you can pick a search value in it. Alternatively, pass arr[x] as the search item. It should return x.
Your code works correctly. You're just not looking for the right keys. The function that prints the values generated into the array prints the loop counter instead:
for (int i = 0; i < arr.Length; i++)
{
Console.Write("{0}\n", i);
}
You need to change it to:
for (int i = 0; i < arr.Length; i++)
{
Console.Write("{0}\n", arr[i]);
}
This will show you the values actually generated.
Comment too short for this so added answer to show how to set basicOperations and still return search position. You declare basicOperations as an out parameter which means the method can change it so the caller can see it when method returns.
public static void Main(string[] args)
{
... ... ...
int basicOperations;
int searchPos = IntArrayBinarySearch(arr, arr[5], out basicOperations);
Console.WriteLine("Found at {0} basic ops={1}", searchPos, basicOperations);
}
public static int IntArrayBinarySearch(int[] data, int item, out int basicOperations)
{
var min = 0;
var N = data.Length;
var max = N - 1;
basicOperations = 0;
basicOperations++;
and at bottom, you don't need to return out parameters, just return -1 to indicate failure as you did before
return -1;

sort without Array.Sort

I just barely understood how to use if statement and "for loop." In addition right now I have to do this
Sort the integer elements within the array from lowest (element 0) to highest (element 4). Do not use the preexisting Array.Sort method; code your own.
This is a homework problem and I don't even know where to start. Can somebody walk me through this?
class Program
{
static void Main(string[] args)
{
int i;
double power = 0, sum = 0;
int[] mArray = new int[5];
Console.WriteLine("Please Enter Number Between 10 and 50 \nMake sure all of your Number entered correctly \notherwise you will need to enter everything again ");
for (i = 0; i < mArray.Length; i++)
{
Console.WriteLine("Please enter your Number.");
mArray[i] = Convert.ToInt32(Console.ReadLine());
if (mArray[i] >= 50 || mArray[i] <= 10)
{
i--;
Console.WriteLine("Please enter numbers only between 10 and 50.");
}
}
for (i = 0; i < mArray.Length; i++)
{
sum = sum + (mArray[i]);
}
double mean = sum / mArray.Length;
for (i = 0; i < mArray.Length; i++)
{
power += Math.Pow((mArray[i] - mean), 2);
}
double rMean = power / (mArray.Length - 1);
Console.WriteLine("Mean {0}", mean);
Console.WriteLine("Variance {0}", rMean);
Console.WriteLine("Here is sorted numbers");
Console.ReadKey();
}
}
There are many sorting algorithms you can try like Insertion Sort
Selection Sort,
Bubble Sort,
Shell Sort,
Merge Sort,
Heap Sort,
Quick Sort,
And many Others.

Integer sequence, in which I have to find the most repeated one. Incase of many repeated numbers, find the lowest value

Theres an integer sequence in which I have to find the most repeated value. Incase of many repeated values, find the lowest value of all the repeated values.
Example: Incase of {-10,17,13,17,-10,21} the result is -10
How far I've got so far:
static void YL2()
{
Random random = new Random();
int mitu = 10, minv = 0, maxv = 20;
int[] mas1 = new int[mitu];
int i;
int lowest;
for (i = 0; i < mitu; i++) mas1[i] = random.Next(minv, maxv);
for (i = 0; i < mitu; i++)
Console.Write("{0,4}", mas1[i]);
Console.Write("\n\n");
int count = 0;
List<int> checkedNumbers = new List<int>();
foreach (int t in mas1)
{
if (!checkedNumbers.Contains(t))
{
foreach (int m in mas1)
{
if (m == t)
{
count++;
}
}
Console.WriteLine("Number {0} is repeated {1} times", t, count);
count = 0;
checkedNumbers.Add(t);
}
}
for (lowest = mas1[0], i = 1; i < mitu; i++)
{
if (mas1[i] < lowest) lowest = mas1[i];
}
Console.Write("Lowest value is {0}\n\n", lowest);
}
The Linq way:
var lowestMaxCountDuplicate = sequence
.GroupBy(i => i)
.OrderByDescending(g => g.Count())
.ThenBy(g => g.Key)
.First().Key;
Demo
The way that doesn't involve replacing all your code you've written with LINQ, as you've done a lot of it yourself:
In your declarations, replace int lowest; with
bool foundOne = false;
int lowest = int.MaxValue;
and we'll keep track of the lowest repeated number as we go along.
After your Console.WriteLine("Number {0} is repeated {1} times", t, count);, add
if (count > 1 && t < lowest)
{
foundOne = true;
lowest = t;
}
i.e. if the number is repeated and it's lower than the lowest repeated number we've found so far, store this one instead. Also, we keep track of whether we've found any repeated numbers. Note that because we set lowest to int.MaxValue to begin with, the first repeated number we found will always be lower than it (or it's the same, in which case it's correct anyway).
Then at the end, rather than your for loop, have the following:
if (foundOne)
Console.Write("Lowest repeated value is {0}\n\n", lowest);
else
Console.Write("No repeated values found\n\n");
just in case every number was different.
This is less effecient than the LINQ, because you're looping through your list far more than you need to, but I thought you might like a solution that doesn't throw away everything you've done.

Project Euler - Number 2 - C#

I'm quite new to programming in C#, and thought that attempting the Euler Problems would be a good idea as a starting foundation. However, I have gotten to a point where I can't seem to get the correct answer for Problem 2.
"Each new term in the Fibonacci sequence is generated by adding the previous two terms. By starting with 1 and 2, the first 10 terms will be:
1, 2, 3, 5, 8, 13, 21, 34, 55, 89, ...
By considering the terms in the Fibonacci sequence whose values do not exceed four million, find the sum of the even-valued terms."
My code is this:
int i = 1;
int j = 2;
int sum = 0;
while (i < 4000000)
{
if (i < j)
{
i += j;
if (i % 2 == 0)
{
sum += i;
}
}
else
{
j += i;
if (j % 2 == 0)
{
sum += j;
}
}
}
MessageBox.Show("The answer is " + sum);
Basically, I think that I am only getting the last two even numbers of the sequence and adding them - but I don't know how to get all of the even numbers of the sequence and add them. Could someone please help me, whilst trying to progress from my starting point?
P.S. - If there are any really bad layout choices, do say as eliminating these now will help me to become a better programmer in the future :)
Thanks a lot in advance.
I just logged in into my Project Euler account, to see the correct answer. As others say, you forgot to add the initial term 2, but otherwise your code is OK (the correct answer is what your code outputs + 2), so well done!
It is pretty confusing though, I think it would look way clearer if you'd use 3 variables, something like:
int first = 1;
int second = 1;
int newTerm = 0;
int sum = 0;
while (newTerm <= 4000000)
{
newTerm = first + second;
if (newTerm % 2 == 0)
{
sum += newTerm;
}
first = second;
second = newTerm;
}
MessageBox.Show("The answer is " + sum);
You need to set the initial value of sum to 2, as you are not including that in your sum with the current code.
Also, although it may be less efficient memory-usage-wise, I would probably write the code something like this because IMO it's much more readable:
var fibonacci = new List<int>();
fibonacci.Add(1);
fibonacci.Add(2);
var curIndex = 1;
while(fibonacci[curIndex] + fibonacci[curIndex - 1] <= 4000000) {
fibonacci.Add(fibonacci[curIndex] + fibonacci[curIndex - 1]);
curIndex++;
}
var sum = fibonacci.Where(x => x % 2 == 0).Sum();
Use an array fib to store the sequence. Its easier to code and debug. At every iteration, you just need to check if the value is even.
fib[i] = fib[i - 1] + fib[i - 2];
if (fib[i] > 4000000) break;
if (fib[i] % 2 == 0) sum += fib[i];
I've solved this a few years ago, so I don't remember how I did it exactly, but I do have access to the forums talking about it. A few hints and an outright solution. The numbers repeat in a pattern. two odds followed by an even. So you could skip numbers without necessarily doing the modulus operation.
A proposed C# solution is
long sum = 0, i0, i1 = 1, i2 = 2;
do
{
sum += i2;
for (int i = 0; i < 3; i++)
{
i0 = i1;
i1 = i2;
i2 = i1 + i0;
}
} while (i2 < 4000000);
Your code is a bit ugly, since you're alternating between i and j. There is a much easier way to calculate fibonacci numbers by using three variables and keeping their meaning the same all the time.
One related bug is that you only check the end condition on every second iteration and in the wrong place. But you are lucky that the cutoff fit your bug(the number that went over the limit was odd), so this is not your problem.
Another bug is that you check with < instead of <=, but since there is no fibonacci number equal to the cutoff this doesn't cause your problem.
It's not an int overflow either.
What remains is that you forgot to look at the first two elements of the sequence. Only one of which is even, so you need to add 2 to your result.
int sum = 0; => int sum = 2;
Personally I'd write one function that returns the infinite fibonacci sequence and then filter and sum with Linq. Fibonacci().TakeWhile(i=> i<=4000000).Where(i=>i%2==0).Sum()
I used a class to represent a FibonacciNumber, which i think makes the code more readable.
public class FibonacciNumber
{
private readonly int first;
private readonly int second;
public FibonacciNumber()
{
this.first = 0;
this.second = 1;
}
private FibonacciNumber(int first, int second)
{
this.first = first;
this.second = second;
}
public int Number
{
get { return first + second; }
}
public FibonacciNumber Next
{
get
{
return new FibonacciNumber(this.second, this.Number);
}
}
public bool IsMultipleOf2
{
get { return (this.Number % 2 == 0); }
}
}
Perhaps it's a step too far but the end result is a function which reads quite nicely IMHO:
var current = new FibonacciNumber();
var result = 0;
while (current.Number <= max)
{
if (current.IsMultipleOf2)
result += current.Number;
current = current.Next;
}
return result;
However it's not going to be as efficient as the other solutions which aren't newing up classes in a while loop. Depends on your requirements I guess, for me I just wanted to solve the problem and move on to the next one.
Hi i have solved this question, check it if its right.
My code is,
#include<iostream.h>
#include<conio.h>
class euler2
{
unsigned long long int a;
public:
void evensum();
};
void euler2::evensum()
{
a=4000000;
unsigned long long int i;
unsigned long long int u;
unsigned long long int initial=0;
unsigned long long int initial1=1;
unsigned long long int sum=0;
for(i=1;i<=a;i++)
{
u=initial+initial1;
initial=initial1;
initial1=u;
if(u%2==0)
{
sum=sum+u;
}
}
cout<<"sum of even fibonacci numbers upto 400000 is"<<sum;
}
void main()
{
euler2 a;
clrscr();
a.evensum();
getch();
}
Here's my implementation:
public static int evenFibonachi(int n)
{
int EvenSum = 2, firstElem = 1, SecondElem = 2, SumElem=0;
while (SumElem <= n)
{
swich(ref firstElem, ref SecondElem, ref SumElem);
if (SumElem % 2 == 0)
EvenSum += SumElem;
}
return EvenSum;
}
private static void swich(ref int firstElem, ref int secondElem, ref int SumElem)
{
int temp = firstElem;
firstElem = secondElem;
secondElem += temp;
SumElem = firstElem + secondElem;
}

Categories

Resources