I know this topic name is similar to another topic but that topic doesn't have the answers i wanted, so...
1st Question:
Let me say i have an array of:
string[] test = new string[5];
for(int x = 0; x <= test.Length - 1; x++)
{
test[x] = "#" + (x + 1) + " element";
Console.WriteLine(test[x]);
}
/*
output:
#1 element
#2 element
#3 element
#4 element
#5 element
*/
and say i wanted to remove "#4 element" from the string array, so that it instead outputs:
/*
output:
#1 element
#2 element
#3 element
#5 element
*/
how do i do that?
[PS:]The Answer i'm looking for is something that's easy to understand for a beginner.
If you want to delete at particular index you can do as :
int[] numbers = { 1,2,3,4,5};
List<int> tmp = new List<int>(numbers);
tmp.RemoveAt(4);
numbers = tmp.ToArray();
But In your case since you are just expecting the element to be invisible and having the array length same :
string[] test = new string[5];
for(int x = 0; x <= test.Length - 1; x++)
{
if(x!=3){
test[x] = "#" + (x + 1) + " element";
Console.WriteLine(test[x]);}
}
You cant just delete an Element from an array, you only can set it to "" for example.
Use List<string> instead.
1st Ans:
You can use list or if you dont want to use list use Linq but it will create a different memory location for array and will store elements there(I suppose).
You can implement linq on your array as below:
test = test.Where(x => !x.Equals("#4 element")).ToArray();
//Print test Now
and now test array does not have "#4 element".
2nd Ans
Instead of Console.WriteLine use Console.Write .
Use List<string> rather than an array.
Use list.RemoveAt(3) to remove the forth element (elements start at 0)
So you might end up with something like the following in order to achieve you desired output:
var test = new List<string>();
for (var x = 1; x <= 5; x++)
{
test.Add(String.Format("#{0} element", x));
}
Console.WriteLine(String.Join(" ", test);
test.RemoveAt(3);
Console.WriteLine(String.Join(" ", test);
Which will give you your desired output of:
#1 element #2 element #3 element #4 element #5 element
#1 element #2 element #3 element #5 element
For your edit. While flushing your o/p just do not flush the outdated element. Using some conditional operator.
Eg: 1. If you want to remove on the basis of array valve then use
string[] test = new string[5];
for(int x = 0; x <= test.Length - 1; x++)
{
test[x] = "#" + (x + 1) + " element";
If (test[x] == "Desired value which you dont want to show")
Console.WriteLine(test[x]);
}
If you want to remove on the basis of array position then use
string[] test = new string[5];
for(int x = 0; x <= test.Length - 1; x++)
{
test[x] = "#" + (x + 1) + " element";
If (x == "Desired index which you dont want to show")
Console.WriteLine(test[x]);
}
While what the others wrote is correct, sometimes you have an array, and you don't want to have a List<>...
public static void Main()
{
string[] test = new string[5];
for(int x = 0; x < test.Length; x++)
{
test[x] = "#" + (x + 1) + " element";
Console.WriteLine(test[x]);
}
Console.WriteLine();
RemoveAt(ref test, 3);
// Or RemoveRange(ref test, 3, 1);
for(int x = 0; x < test.Length; x++)
{
Console.WriteLine(test[x]);
}
}
public static void RemoveAt<T>(ref T[] array, int index)
{
RemoveRange(ref array, index, 1);
}
public static void RemoveRange<T>(ref T[] array, int start, int count)
{
if (array == null)
{
throw new ArgumentNullException("array");
}
if (start < 0 || start > array.Length)
{
throw new ArgumentOutOfRangeException("start");
}
if (count < 0 || start + count > array.Length)
{
throw new ArgumentOutOfRangeException("count");
}
if (count == 0)
{
return;
}
T[] orig = array;
array = new T[orig.Length - count];
Array.Copy(orig, 0, array, 0, start);
Array.Copy(orig, start + count, array, start, array.Length - start);
}
Two simple methods to remove elements of an array (RemoveAt and RemoveRange), with full example of use.
Arrays have fixed size, so if you want add or remove element from them you need to deal with resizing. Therefore in C# it is recommended to use Lists instead (they deal with it themselves).Here is nice post about Arrays vs Lists.
But if you really want to do it with Array or have a reason for that, you could do it this way:
class Program
{
static void Main(string[] args)
{
int[] myArray = { 1, 2, 3, 4, 5 };
//destination array
int[] newArray = new int[myArray.Length-1];
//index of the element you want to delete
var index = 3;
//get and copy first 3 elements
Array.Copy(myArray, newArray, index);
//get and copy remaining elements without the 4th
Array.Copy(myArray, index + 1, newArray, index, myArray.Length-(index+1));
//Output newArray
System.Text.StringBuilder sb = new System.Text.StringBuilder();
for (int i = 0; i < newArray.Length; i++)
{
sb.Append(String.Format("#{0} {1}", i + 1, newArray[i]));
if (!(i == newArray.Length - 1))
{
sb.Append(", ");
}
}
Console.Write(sb.ToString());
Console.ReadLine();
}
See My solution... let me know if does helps...
class Program
{
// this program will work only if you have distinct elements in your array
static void Main(string[] args)
{
string[] test = new string[5];
for (int x = 0; x <= test.Length - 1; x++)
{
test[x] = "#" + (x + 1) + " element";
Console.WriteLine(test[x]);
}
Console.ReadKey();
Program p = new Program();
test = p.DeleteKey(test, "#3 element"); // pass the array and record to be deleted
for (int x = 0; x <= test.Length - 1; x++)
{
Console.WriteLine(test[x]);
}
Console.ReadKey();
}
public string[] DeleteKey(string[] arr, string str)
{
int keyIndex = 0;
if (arr.Contains(str))
{
for (int i = 0; i < arr.Length - 1; i++)
{
if (arr[i] == str)
{
keyIndex = i; // get the index position of string key
break; // break if index found, no need to search items for further
}
}
for (int i = keyIndex; i <= arr.Length - 2; i++)
{
arr[i] = arr[i+1]; // swap next elements till end of the array
}
arr[arr.Length - 1] = null; // set last element to null
return arr; // return array
}
else
{
return null;
}
}
}
Related
I have an array of strings which represents the lines of a textfile. Now I want to search the line where my given argument occurs and return this line plus the four adjacent lines.
The problem occurs when my searched string is found in the last or first two indexes. Obviously this is because I want the index[i+2] when there is none.
Ideally, if the last line is the prime one, it should return only this and the two lines before it because there aren't two after it.
So is there a Best Practice how to solve this issue other then adding an if-statement in front of every of the five line inside the "contains"-if-statement?
ReadAsString converts the content of the textfile into the array of strings _textAsString
public string[] GetNearestInstructions(string foo)
{
try
{
string[] stringsToReturn = new string[5];
if (!this.ReadAsString())
return null;
else if (foo == null)
return null;
else
{
for (int i = 0; i < _textAsString.Length; i++)
{
if (_textAsString[i].Contains(foo))
{
stringsToReturn[0] = _textAsString[i - 2];
stringsToReturn[1] = _textAsString[i - 1];
stringsToReturn[2] = _textAsString[i];
stringsToReturn[3] = _textAsString[i + 1];
stringsToReturn[4] = _textAsString[i + 2];
}
}
if (stringsToReturn != null)
return stringsToReturn;
else
return null;
}
}
catch (Exception)
{
throw;
}
}
You might do something like
...
if (_textAsString[i].Contains(foo))
{
int rangoLow = Math.Max(i - 2, 0);
int rangeHigh = Math.Min(i + 2, _textAsString.Length - 1);
for (int i = rangeLow; i <= rangeHigh; i++)
{
stringsToReturn[i - rangeLow] = _textAsString[i];
}
Assuming that you need the result as array in the exact same format as you are returning it right now, that is with null items at begin or end, this would be the way I would do it:
public static string[] GetNearestInstructions(string foo)
{
if (foo != null && this.ReadAsString())
{
int index = Array.IndexOf(_textAsString, foo);
if (index >= 0)
{
string[] stringsToReturn = new string[5];
stringsToReturn[0] = index > 1 ? _textAsString[index - 2] : null;
stringsToReturn[1] = index > 0 ? _textAsString[index - 1] : null;
stringsToReturn[2] = _textAsString[index];
stringsToReturn[3] = index < _textAsString.Length - 1 ? _textAsString[index + 1] : null;
stringsToReturn[4] = index < _textAsString.Length - 2 ? _textAsString[index + 2] : null;
return stringsToReturn;
}
}
return null;
}
Things get easier if you are fine with changing the number of returned items, see the other answers then.
You need to adjust the first + last indices as needed. See code below. Also I changed stringsToReturn to a List because it is more convenient, and because there is no point in always returning an array of 5 items if there are fewer than 5.
List<string> stringsToReturn = new List<string>();
for (int i = 0; i < _textAsString.Length; i++)
{
if (_textAsString[i].Contains(foo))
{
var firstIndex = Math.Max(0, i - 2);
var lastIndex = Math.Min(_textAsString.Length - 1, i + 2);
for (int j = firstIndex; j <= lastIndex; j++)
stringsToReturn.Add(_textAsString[j]);
return stringsToReturn.ToArray();
}
}
// foo not found
return null;
Note, that if _textAsString is string (not collection of strings), then this function should take char as parameter, and return collection of chars (or single string).
Hi I am trying to loop through a set of int variables and do an if on each one. I.e.
int a0, a1, a2,a3;
for (int I=0; I < 3; I++)
{
if("a" + I > 10)
{
// do something
}
}
Is this possible?
If you want to iterate you need a collection
IEnumerable<int> numbers = new List<int> { 1, 2, 3, 10 };
foreach (var item in numbers)
{
if(item > 10)
{
// do something
}
}
When you write "a" + I all you are doing is create a string that is a concatenation of the two pieces and is not the parameter you defined before
You can then proceed and use linq:
var filtered = numbers.Where(item => item > 10)
You can use array as variable so you can iterate that :
int[] a = new int[3];
a[0] = 5;
a[1] = 10;
a[2] = 15;
for (int I = 0; I < 3; I++)
{
if (a[I] > 10)
{
// do something, example:
Console.WriteLine(a[I])
}
}
Result :
15
i'm creating a program which requires to check every possible permutation. let's say we have 1,2,3 the program will work just fine and show me all the possible ones : 1,3,2 2,1,3 2,3,1 3,1,2 and 3,2,1 however i also want it to be able to try such combinations
1,1,1
2,2,2
1,2,2
3,3,2
i.e include absolutely every possible combination.. Here's my code :
public static bool NextPermutation<T>(T[] elements) where T : IComparable<T>
{
// More efficient to have a variable instead of accessing a property
var count = elements.Length;
// Indicates whether this is the last lexicographic permutation
var done = true;
// Go through the array from last to first
for (var i = count - 1; i > 0; i--)
{
var curr = elements[i];
// Check if the current element is less than the one before it
if (curr.CompareTo(elements[i - 1]) < 0)
{
continue;
}
// An element bigger than the one before it has been found,
// so this isn't the last lexicographic permutation.
done = false;
// Save the previous (bigger) element in a variable for more efficiency.
var prev = elements[i - 1];
// Have a variable to hold the index of the element to swap
// with the previous element (the to-swap element would be
// the smallest element that comes after the previous element
// and is bigger than the previous element), initializing it
// as the current index of the current item (curr).
var currIndex = i;
// Go through the array from the element after the current one to last
for (var j = i + 1; j < count; j++)
{
// Save into variable for more efficiency
var tmp = elements[j];
// Check if tmp suits the "next swap" conditions:
// Smallest, but bigger than the "prev" element
if (tmp.CompareTo(curr) < 0 && tmp.CompareTo(prev) > 0)
{
curr = tmp;
currIndex = j;
}
}
// Swap the "prev" with the new "curr" (the swap-with element)
elements[currIndex] = prev;
elements[i - 1] = curr;
// Reverse the order of the tail, in order to reset it's lexicographic order
for (var j = count - 1; j > i; j--, i++)
{
var tmp = elements[j];
elements[j] = elements[i];
elements[i] = tmp;
}
// Break since we have got the next permutation
// The reason to have all the logic inside the loop is
// to prevent the need of an extra variable indicating "i" when
// the next needed swap is found (moving "i" outside the loop is a
// bad practice, and isn't very readable, so I preferred not doing
// that as well).
break;
}
// Return whether this has been the last lexicographic permutation.
return done;
}
This is a simple example of how i use it
var arr = new[] {0, 1, 2,};
var conditions = new[] {true, false, true};
int count = 0;
while (!NextPermutation(arr))
{
List<bool> tempConditions = new List<bool>();
for (int i = 0; i < arr.Length; i++)
{
tempConditions.Add(conditions[arr[i]]);
Console.Write(tempConditions[i] + " ");
}
count++;
Console.WriteLine();
}
Console.WriteLine("count : {0}", count);
You can do this with a method that returns IEnumerable<IEnumerable<T>> like so:
using System;
using System.Collections.Generic;
using System.Linq;
namespace Demo
{
public static class Program
{
public static void Main()
{
string[] test = {"A", "B", "C", "D"};
foreach (var perm in PermuteWithRepeats(test))
Console.WriteLine(string.Join(" ", perm));
}
public static IEnumerable<IEnumerable<T>> PermuteWithRepeats<T>(IEnumerable<T> sequence)
{
return permuteWithRepeats(sequence, sequence.Count());
}
private static IEnumerable<IEnumerable<T>> permuteWithRepeats<T>(IEnumerable<T> sequence, int count)
{
if (count == 0)
{
yield return Enumerable.Empty<T>();
}
else
{
foreach (T startingElement in sequence)
{
IEnumerable<T> remainingItems = sequence;
foreach (IEnumerable<T> permutationOfRemainder in permuteWithRepeats(remainingItems, count - 1))
yield return new[]{startingElement}.Concat(permutationOfRemainder);
}
}
}
}
}
1,1,2 2,2,2 and such aren't permutations - they are variations. There will be count ^ count of them
You can generate them like this:
// you can do precise powering if needed
double number_of_variations = Math.Pow(count, count);
T[] result = new T[count];
for (int i = 0; i < number_of_variations; ++i) {
int x = i;
for (int j = 0; j < count; ++j) {
result[j] = elements[x % count];
x /= count;
}
// do something with one of results
}
I have this array of integers:-
int[] numbers = new int[] { 10, 20, 30, 40 };
I am trying to create an array which will have first element, last element, second element, second-last element and so on..
So, my resulting output will be:-
int[] result = {10,40,20,30};
This was my approach, in one loop start from first and go till the middle & in second loop start from last and get to the middle and select items accordingly, but I totally messed it up. Here is my attempted code:-
private static IEnumerable<int> OrderedArray(int[] numbers)
{
bool takeFirst = true;
if (takeFirst)
{
takeFirst = false;
for (int i = 0; i < numbers.Length / 2; i++)
{
yield return numbers[i];
}
}
else
{
takeFirst = true;
for (int j = numbers.Length; j < numbers.Length / 2; j--)
{
yield return numbers[j];
}
}
}
Need Help.
You might try this:
int[] result = numbers.Zip(numbers.Reverse(), (n1,n2) => new[] {n1, n2})
.SelectMany(x =>x)
.Take(numbers.Length)
.ToArray();
Explanation: This approach basically pairs up the elements of the original collection with the elements of its reverse ordered collection (using Zip). So you get a collection of pairs like [first, last], [second, second from last], etc.
It then flattens those collection of pairs into a single collection (using SelectMany). So the collection becomes [first, last, second, second from last,...].
Finally, we limit the number of elements to the length of the original array (n). Since we are iterating through twice as many elements (normal and reverse), it works out that iterating through n elements allow us to stop in the middle of the collection.
As a different approach, this is a modification on your existing method:
private static IEnumerable<int> OrderedArray(int[] numbers)
{
var count = (numbers.Length + 1) / 2;
for (int i = 0; i < count; i++)
{
yield return numbers[i];
int reverseIdx = numbers.Length - 1 - i;
if(i != reverseIdx)
yield return numbers[reverseIdx];
}
}
ok,
public static class Extensions
{
public static IEnumerable<T> EndToEnd<T>(this IReadOnlyList<T> source)
{
var length = source.Count;
var limit = length / 2;
for (var i = 0; i < limit; i++)
{
yield return source[i];
yield return source[length - i - 1];
}
if (length % 2 > 0)
{
yield return source[limit];
}
}
}
Which you could use like this,
var result = numbers.EndToEnd().ToArray();
more optimally,
public static class Extensions
{
public static IEnumerable<T> EndToEnd<T>(this IReadOnlyList<T> source)
{
var c = source.Count;
for (int i = 0, f = 0, l = c - 1; i < c; i++, f++, l--)
{
yield return source[f];
if (++i == c)
{
break;
}
yield return source[l];
}
}
}
no divide or modulus required.
With a simple for;
int len = numbers.Length;
int[] result = new int[len];
for (int i = 0, f = 0, l = len - 1; i < len; f++, l--)
{
result[i++] = numbers[f];
if (f != l)
result[i++] = numbers[l];
}
Based on Selman22's now deleted answer:
int[] numbers = new int[] { 10, 20, 30, 40 };
int[] result = numbers
.Select((x,idx) => idx % 2 == 0
? numbers[idx/2]
: numbers[numbers.Length - 1 -idx/2])
.ToArray();
result.Dump();
(The last line is LinqPad's way of outputting the results)
Or in less LINQy form as suggested by Jeppe Stig Nielsen
var result = new int[numbers.Length];
for (var idx = 0; idx < result.Length; idx++) {
result[idx] = idx % 2 == 0 ? numbers[idx/2] : numbers[numbers.Length - 1 -idx/2];
}
The principle is that you have two sequences, one for even elements (in the result) and one for odd. The even numbers count the first half of the array and the odds count the second half from the back.
The only modification to Selman's code is adding the /2 to the indexes to keep it counting one by one in the right half while the output index (which is what idx basically is in this case) counts on.
Came up with this
static void Main(string[] args)
{
List<int> numbers = new List<int>() { 10, 20, 30, 40, 50, 60, 70};
List<int> numbers2 = new List<int>();
int counter1 = 0;
int counter2 = numbers.Count - 1;
int remainder = numbers.Count % 2 == 0 ? 1: 0;
while (counter1-1 < counter2)
{
if (counter1 + counter2 % 2 == remainder)
{
numbers2.Add(numbers[counter1]);
counter1++;
}
else
{
numbers2.Add(numbers[counter2]);
counter2--;
}
}
string s = "";
for(int a = 0; a< numbers2.Count;a++)
s+=numbers2[a] + " ";
Console.Write(s);
Console.ReadLine();
}
This late answer steals a lot from the existing answers!
The idea is to allocate the entire result array at once (since its length is known). Then fill out all even-indexed members first, from one end of source. And finally fill out odd-numbered entries from the back end of source.
public static TElement[] EndToEnd<TElement>(this IReadOnlyList<TElement> source)
{
var count = source.Count;
var result = new TElement[count];
for (var i = 0; i < (count + 1) / 2; i++)
result[2 * i] = source[i];
for (var i = 1; i <= count / 2; i++)
result[2 * i - 1] = source[count - i];
return result;
}
Came up with this
public int[] OrderedArray(int[] numbers)
{
int[] final = new int[numbers.Length];
var limit=numbers.Length;
int last = numbers.Length - 1;
var finalCounter = 0;
for (int i = 0; finalCounter < numbers.Length; i++)
{
final[finalCounter] = numbers[i];
final[((finalCounter + 1) >= limit ? limit - 1 : (finalCounter + 1))] = numbers[last];
finalCounter += 2;
last--;
}
return final;
}
My sorting code not giving correct result it is not sortint the given list properly while i am not getting the error please check it,
static void Main(string[] args)
{
List<int> a = new List<int>(new int[] { 3, 7, 6, 1, 8, 5 });
int temp;
// foreach(int i in a)
for(int i=1; i<=a.Count; i++)
for(int j=0; j<a.Count-i; j++)
if (a[j] > a[j + 1])
{
temp = a[j];
a[j] = a[j + 1];
a[j + 1] = temp;
Console.WriteLine(a[j]);
}
Console.Read();
}
i could not understand your code and i do not know C#. But anyways, here is the sorting logic for bubble sort (written in c).
//assuming there are n elements in the array a[]
for(i=0; i<n; i++)
{ for(j=1; j<n-i; j++)
{ if(a[j] < a[j-1])
{ temp = a[j];
a[j] = a[j-1];
a[j-1] = temp;
}
}
}
and you can also refer to:
www.sorting-algorithms.com/bubble-sort
What you posted is not a implementation of the Bubble Sort algorithm. You forgot to loop while no number is swapped anymore. Here is a Bubble Sort implementation written by John Skeet. The stillGoing check is what at least is missing in your implementation:
public void BubbleSort<T>(IList<T> list);
{
BubbleSort<T>(list, Comparer<T>.Default);
}
public void BubbleSort<T>(IList<T> list, IComparer<T> comparer)
{
bool stillGoing = true;
while (stillGoing)
{
stillGoing = false;
for (int i = 0; i < list.Length-1; i++)
{
T x = list[i];
T y = list[i + 1];
if (comparer.Compare(x, y) > 0)
{
list[i] = y;
list[i + 1] = x;
stillGoing = true;
}
}
}
}
remove the console.write from the nested loops. place console.write outside the nested loops in a new for loop or foreach.
then you will get the correct order. otherwise, the logic of bubble sort is correct