Linear Search Problem [closed] - c#

Closed. This question needs to be more focused. It is not currently accepting answers.
Want to improve this question? Update the question so it focuses on one problem only by editing this post.
Closed 3 years ago.
Improve this question
My program has no compile errors but the output is incorrect. Example input:
size of array: 5
input numbers: 5 4 3 2 1
//sorted: 1 2 3 4 5
search: 1
output: number 1 found at index 4
the output should be number 1 found at index 0 since the numbers were sorted already. How will I change it to this.
int[] nums = new int[100];
int SizeNum;
bool isNum = false;
private void ExeButton_Click(object sender, EventArgs e)
{
int i, loc, key;
Boolean found = false;
string SizeString = SizeTextBox.Text;
isNum = Int32.TryParse(SizeString, out SizeNum);
string[] numsInString = EntNum.Text.Split(' '); //split values in textbox
for (int j = 0; j < numsInString.Length; j++)
{
nums[j] = int.Parse(numsInString[j]);
}
if (SizeNum == numsInString.Length)
{
Array.Sort(numsInString);
key = int.Parse(SearchTextBox.Text);
ResultText.AppendText("Sorted: ");
for (i = 0; i < SizeNum; i++)
ResultText.AppendText(" " + numsInString[i]);
ResultText.AppendText("\n\n");
{
for (loc = 0; loc < SizeNum; loc++)
{
if (nums[loc] == key)
{
found = true;
break;
}
}
if (found == true)
ResultText.AppendText("Number " + key + " Found At Index [" + loc + "]\n\n");
else
ResultText.AppendText("Number " + key + " Not Found!\n\n");
}
}
}

You're sorting numsInString but then searching nums. nums is being populated before the search, so you're seeing the results of searching the unsorted numbers.
Once you've parsed numsInStrings into nums, you should be working with the latter array only. Make sure that's the one you're sorting and searching through.
In other words, once you replace the current sort call with
Array.Sort(nums);
your code will be fine.
Updated:
You actually need another fix. Right now, you're initializing nums to be an array of size 100. By default, each element will be 0. So even though you put numbers in the first five elements, when you sort the array, you end up with 95 0's, followed by 1 2 3 4 5.
You should delay initializing nums until you've seen how big numsInString is:
string[] numsInString = EntNum.Text.Split(' '); //split values in textbox
nums = new int[numsInString.Length];
for (int j = 0; j < numsInString.Length; j++)
{
nums[j] = int.Parse(numsInString[j]);
}
Now when you sort nums, you'll see only the numbers you entered.

you are sorting the numsInString array, but still searching into the nums array.
for (loc = 0; loc < SizeNum; loc++)
{
if (numsInString[loc] == key)
{
found = true;
break;
}
}

You're parsing numsInString then you're sorting it. (I suspect the sort won't do what you want, either.)
I think you really want to be sorting nums instead:
Array.Sort(nums);
Having said that, there are simpler ways of achieving the end result - such as using IndexOf to find the index of a value in an array.
It's also rather unclear why you've got braces here:
for (i = 0; i < SizeNum; i++)
ResultText.AppendText(" " + numsInString[i]);
ResultText.AppendText("\n\n");
{
...
}
That makes it look like you've got a loop with a body, but it's actually equivalent to:
for (i = 0; i < SizeNum; i++)
{
ResultText.AppendText(" " + numsInString[i]);
}
ResultText.AppendText("\n\n");
{
...
}
... the braces serve no purpose here, and merely harm readability.

Related

Increasing sequence in one dimensional array

You're given an array of integers,in case if you see subsequence in which each following bigger than the previous on one(2 3 4 5) you have to rewrite this subsequence in the resulting array like this 2 - 5 and then the rest of the array. So in general what is expected when you have 1 2 3 5 8 10 11 12 13 14 15 the output should be something like 1-3 5 8 10-15.
I have my own idea but can't really implement it so all I managed to do is:
static void CompactArray(int[] arr)
{
int[] newArr = new int[arr.length];
int l = 0;
for (int i = 0,k=1; i <arr.length ; i+=k,k=1) {
if(arr[i+1]==arr[i]+1)
{
int j = i;
while (arr[j+1]==arr[j]+1)
{
j++;
k++;
}
if (k>1)
{
}
}
else if(k==1)
{
newArr[i] = arr[i];
}
}
In short here I walk through the array and checking if next element is sum of one and previous array element and if so I'm starting to walk as long as condition is true and after that i just rewriting elements under indices and then move to the next.
I expect that people will help me to develop my own solution by giving me suggestions instead of throwing their own based on the tools which language provides because I had that situation on the russian forum and it didn't help me, and also I hope that my explanation is clear because eng isn't my native language so sorry for possible mistakes.
If I understand the problem correctly, you just need to print the result on the screen, so I'd start with declaring the variable which will hold our result string.
var result = string.Empty
Not using other array to store the state will help us keep the code clean and much more readable.
Let's now focus on the main logic. We'd like to loop over the array.
for (int i = 0; i < array.Length; i++)
{
// Let's store the initial index of current iteration.
var beginningIndex = i;
// Jump to the next element, as long as:
// - it exists (i + 1 < array.Length)
// - and it is greater from current element by 1 (array[i] == array[i+1] - 1)
while (i + 1 < array.Length && array[i] == array[i+1] - 1)
{
i++;
}
// If the current element is the same as the one we started with, add it to the result string.
if (i == beginningIndex)
{
result += $"{array[i]} ";
}
// If it is different element, add the range from beginning element to the one we ended with.
else
{
result += $"{array[beginningIndex]}-{array[i]} ";
}
}
All that's left is printing the result:
Console.WriteLine(result)
Combining it all together would make the whole function look like:
static void CompactArray(int[] array)
{
var result = string.Empty;
for (int i = 0; i < array.Length; i++)
{
var beginningIndex = i;
while (i + 1 < array.Length && array[i] == array[i+1] - 1)
{
i++;
}
if (i == beginningIndex)
{
result += $"{array[i]} ";
}
else
{
result += $"{array[beginningIndex]}-{array[i]} ";
}
}
Console.WriteLine(result);
}

How to make only chosen characters uppercase in C# [closed]

Closed. This question needs to be more focused. It is not currently accepting answers.
Want to improve this question? Update the question so it focuses on one problem only by editing this post.
Closed 3 years ago.
Improve this question
I want to make every other letter uppercase, how do I do that?
Code:
String a = ("aábdeéðfghiíjklmnoóprstuúvxyýþæö");
for (int i=0; i < a.Length; i++)
{
Console.Write(a.ToUpper()[i]+ ",");
}
Using Linq:
string a = "aábdeéðfghiíjklmnoóprstuúvxyýþæö";
var converted =
new string(a.Select((ch, i) => ((i % 2) == 0) ? ch : Char.ToUpper(ch)).ToArray());
Console.WriteLine(converted);
Increment your loop by 2.
Example:
String a = ("aábdeéðfghiíjklmnoóprstuúvxyýþæö");
for (int i=0; i<a.Length; i+=2)
Console.Write(a.ToUpper()[i]+ ",");
For every even alphabet start loop from 0 and for odd start from 1.
Linq answer is very good and has the advantage to be one liner, but a normal loop here is twice faster than the Linq solution
char[] a = "aábdeéðfghiíjklmnoóprstuúvxyýþæö".ToCharArray();
for (int i = 0; i < a.Length; i++)
{
if (i % 2 != 0)
{
a[i] = Char.ToUpper(a[i]);
}
}
string result = new string(a);
Using LINQ to go through each char in the string. If it is divisible by 2 then that means its every other letter. So make that upper case, if not divisible by 2 then leave it as it is. Rejoin all the chars together in an array then convert that back into a string.
String a = ("aábdeéðfghiíjklmnoóprstuúvxyýþæö");
var convertedString = new string(a
.Select((c, i) => (i + 1) % 2 == 0 ? Char.ToUpper(c) : c)
.ToArray());
String a = ("aábdeéðfghiíjklmnoóprstuúvxyýþæö");
for (int i=0; i<a.Length; i++)
{
if (i % 2 == 0)
{
a = a.Substring(0, i) + a.Substring(i, 1).ToUpper() + a.Substring(i);
}
}
The % symbol is modulo, in this context if the index if divisible by 2 make the symbol upper case.
EDIT: as correctly pointed out, string are immutable, I've edited appropriately. This most likely isn't the most efficient way of doing this, I'd recommend using LINQ for a more efficient algorithm
You can use Linq.
string oldString = "aábdeéðfghiíjklmnoóprstuúvxyýþæö";
string alternatedString = string.Concat(
oldString.ToLower().Select((character, index) => index % 2 == 0 ? character : char.ToUpper(character)));
Output: aÁbDeÉðFgHiÍjKlMnOóPrStUúVxYýÞæÖ
Or
string oldString = "aábdeéðfghiíjklmnoóprstuúvxyýþæö";
StringBuilder alternatedString = new StringBuilder();
for(int index=0; index<oldString.Length; index++)
{
if(index % 2 == 0)
alternatedString.Append(oldString[index].ToString().ToLower());
else
alternatedString.Append(oldString[index].ToString().ToUpper());
}
Output: aÁbDeÉðFgHiÍjKlMnOóPrStUúVxYýÞæÖ

Project Euler #23 [closed]

Closed. This question needs details or clarity. It is not currently accepting answers.
Want to improve this question? Add details and clarify the problem by editing this post.
Closed 6 years ago.
Improve this question
I'm currently trying to solve the project euler problem number 23 :
A perfect number is a number for which the sum of its proper divisors is exactly equal to the number. For example, the sum of the proper divisors of 28 would be 1 + 2 + 4 + 7 + 14 = 28, which means that 28 is a perfect number.
A number n is called deficient if the sum of its proper divisors is less than n and it is called abundant if this sum exceeds n.
As 12 is the smallest abundant number, 1 + 2 + 3 + 4 + 6 = 16, the smallest number that can be written as the sum of two abundant numbers is 24. By mathematical analysis, it can be shown that all integers greater than 28123 can be written as the sum of two abundant numbers. However, this upper limit cannot be reduced any further by analysis even though it is known that the greatest number that cannot be expressed as the sum of two abundant numbers is less than this limit.
Find the sum of all the positive integers which cannot be written as the sum of two abundant numbers.
However my code is not giving correct result while it seems to be completely fine. Am I calculating more than the enough numbers ?
private static void Main()
{
List<int> AbudantNumbers = new List<int>();
long sum = 0;
for (int i = 12; i <= 28123; i++)
{
int abudantNumber = GetProperDivisor(i);
if (abudantNumber > i)
{
AbudantNumbers.Add(i);
}
}
for (int k = 1; k <= 28123; k++)
{
int count = 0;
for (int i = 0; i < AbudantNumbers.Count; i++)
{
count = 0;
if (AbudantNumbers[i] > k)
{
break;
}
for (int j = i; j < AbudantNumbers.Count; j++)
{
if (AbudantNumbers[j] > k)
{
break;
}
if (AbudantNumbers[i] + AbudantNumbers[j] == k)
{
count++;
break;
}
}
}
if (count == 0)
{
sum += k;
}
}
Console.WriteLine(sum);
Console.ReadKey();
}
private static int GetProperDivisor(int input)
{
int sum = 1;
for (int i = 2; i <= input / 2; i++)
{
if (input%i == 0)
{
sum += i;
}
}
return sum;
}
My result is : 297632990
Correct result is : 4179871
Quite big difference when there are no obvious mistakes in my code.
My second approach :
for (int k = 1; k <= 28123; k++)
{
var k1 = k;
int count =
(from t1 in AbudantNumbers.TakeWhile(t1 => t1 <= k1) let a = t1 select t1).Count(
t1 => AbudantNumbers.TakeWhile(t => t <= k).Any(t => t1 + t == k));
if (count == 0)
{
sum += k;
}
}
My idea is to get all the abundant numbers lesser than 28123 than check all the integers lesser than 28123 (everything above have a sum of 2 abundant numbers) than rotate all the abundant numbers and lastly check if abundantNumber1 + abundantNumber2 == currentNumber if so we break out of the loop because we need only the ones that don't have a sum of 2 abundant numbers.
When you find that the current number k is the sum of two abundant numbers a[i] + a[j], you set the count and then break out of the loop – out of the inner loop over j, that is.
That means that you still consider all remaining is, for which you reset the count. Effectively, you consider only the last abundant number that is smaller or equal to k. It is not likely that the sum of the two numbers involves this number, so your condition for adding the numbers, count == 0 will be wrong in most cases.
You must break out of the two innermost loops when you find out that k == a[i] + a[j]. C# doesn't seem to have labelled loops, so it is probably best to refactor the the inner loops into a function that takes the list of abundant numbers and k as arguments; you can then simply return true when your condition is met.
As a quick but ugly fix, you can add
if (count) break;
after the loop over j.
Your approach is very ineffective, though. It might be better to write only two nested loops over all abundant numbers and then add their sums to a set when they are smaller than 28124. Then add all numbers from 1 to 28124 that are not in the set.

How do I check if my array contains my guessed numbers respectively?

If my array contains random numbers in respective order (1,2,3,4,5,6,7) and I want to create another array of my guesses (1,4,2,4,5,6,7), I would like to see how many I got correct, respectively.
Here's my code:
Console.WriteLine("Can you guess the numbers that have appeared on the screen respectively?");
for (int i = 1; i < num.Length; i++)
{
Console.Write(i + ". ");
string temp = Console.ReadLine();
userGuess[i] = Convert.ToInt32(temp);
}
for (int i = 1; i < num.Length; i++)
{
if (num[i] == userGuess[i])//Here's my problem. I am unable to
//test whether my guess resides in the num array.
{
count++;
}
}
Console.WriteLine("You got " + count + " guesses right.");
Count should end up with 5 correct if I was to choose 1,4,2,4,5,6,7, judging that my num array contains 1,2,3,4,5,6,7 respectively.
Thanks!
Like #failedprogramming said, you missmatch index between array userGuess and num.
I know you want to start user input with no."1" but, it will get your userguess array will be moving in wrong index.
1 2 3 4 5 6 7
blank 1 4 2 4 5 6
So, you have no right answer.
Maybe you can use this:
Console.WriteLine("Can you guess the numbers that have appeared on the screen respectively?");
for (int i = 1; i < num.Length+1; i++)
{
Console.Write(i + ". ");
string temp = Console.ReadLine();
userGuess[i-1] = Convert.ToInt32(temp);
}
for (int i = 0; i < num.Length; i++)
{
if (num[i] == userGuess[i])//Here's my problem. I am unable to
//test whether my guess resides in the num array.
{
count++;
}
}
Console.WriteLine("You got " + count + " guesses right.");
Since the two arrays are of equal length, you can use LINQ's Zip() method:
var result = num.Zip(userGuess, (n, u) => n == u ? 1 : 0).Sum();
This compares each corresponding element in the two lists, returning 1 for a match or 0 for a non-match, then adds up the values. The result is effectively the number of matches.

Loop to write a cimma separated list of items [closed]

Closed. This question needs debugging details. It is not currently accepting answers.
Edit the question to include desired behavior, a specific problem or error, and the shortest code necessary to reproduce the problem. This will help others answer the question.
Closed 7 years ago.
Improve this question
I need to write a for loop that prints 49 through 1, with each value separated by a comma. So, it must not print a comma after the last value.
I have this so far and have no clue , after an hour of research, what else to do.
For (int i = 49; i >= 1; i--)
{
Console.WriteLine(i + ",");
}
Just check where you are in your loop to know if you need to print the comma.
public static void Test()
{
for (int i = 49; i >= 1; i--)
{
Console.WriteLine(i + (i != 1 ? "," : ""));
}
Console.ReadLine();
}
Check if you are at the last item, and don't write the comma in that case:
for (int i = 49; i >= 1; i--) {
Console.Write(i);
if (i > 1) {
Console.Write(",");
}
Console.WriteLine();
}
(There are alternatives that are a little more elegant, but this is closest to your original code. You can for example write the comma before the number and skip the first comma.)
You can use String.Join
List<string> numbers = new List<string>();
for (int i = 49; i >= 1; i--) {
numbers.Add(i.ToString());
}
string numberWithCommas = String.Join(",", numbers);
Console.WriteLine(numberWithCommas);
Or you can put in a if condition to check for the last element and conditionally print your comma.
The String.Join would be a neater way to do this operation. However as pointed out by #CommuSoft, if you are doing this operation for a large list of numbers, the memory used may be high in this operation.
Try this:
for (int i = 49; i >= 1; i--)
{
Console.Write("{0}{1}", i, i == 1 ? string.Empty : ",");
}
Your not keeping track of your value.
var content = String.Empty;
for(var i = 49; i >= 1; i--)
content += (i + ",");
Console.WriteLine(content);
Once you have a value, then you apply it. The problem your having is the scope never remains, it applies to a new line.
The value of i determines when to add the comma:
For (int i = 49; i >= 1; i--)
{
Console.WriteLine(i >= 1 ? i + "," : i);
}

Categories