Reverse elements of a string array - c#

string[] myString = {"a","b","c","d"}
//Reverse string algorithm here
myString = {"d","c","b","a"}
I have been asked to do so in an interview without the help of any temporary variable or .NET class, string methods, etc to reverse the elements of the same string array. I was told to use basic programming constructs like loops. Since, I am up for another interview today, I am in a hurry to know whether this is actually possible because I could not find a solution to this.

Here you go, no support variables, no .net functions :) But it makes the assumptions that all the strings in the array have length 1 ( as they do in the code you posted).
string[] myString = {"a","b","c","d", "e"};
for(int i = 0; i < myString.Length/2; i++)
{
myString[i] += myString[myString.Length -1 -i];
myString[myString.Length -1 -i] = ""+myString[i][0];
myString[i] = "" + myString[i][1];
}

Since you cannot use a temporary variable, the best I can think of is appending the strings first and then removing the appended part again:
// append last strings to first strings
for(int i = 0; i < myString.Length / 2; i++)
{
myString[i] = myString[i] + myString[myString.Length - i - 1];
}
// copy first half to last half
for(int i = myString.Length / 2 + 1; i < myString.Length; i++)
{
myString[i] = myString[myString.Length - i - 1]
.SubString(0,
myString[myString.Length - i - 1].Length
- myString[i].Length);
}
// remove useless part from first half
for(int i = 0; i < myString.Length / 2; i++)
{
myString[i] = myString[i].SubString(
myString[myString.Length - i - 1].Length
- myString[i].Length);
}
Stupid approach? Yes. But no additional variables are involved.

string[] myString = {"a","b","c","d"}
for(int = (myString.Length - 1); int >= 0; i--) {
string rev = myString[i];
Console.Write(rev);
}

Sorry I posted a wrong answer... here's the verified one:
int k = len - 1;
for(int i = 0; i<len/2; i++)
{
myString[i] = myString[i]+"."+myString[k--];
}
for(int i = len/2; i<len; i++)
{
myString[i] = myString[k].substring(0, 1);
myString[k] = myString[k--].substring(2,3);
}
However, just consider this a pseudo-code... I did not check for .NET syntax.

The right answer in your interview is "Why would you NOT use the class libraries?" But then say, "Well if I needed to write a customized method because the libraries don't support the need...". Then I would show both methods and argue when to use each method. If they had a problem with this explanation then I wouldn't want to work there anyway.
With Libraries:
string[] myString = {"a","b","c","d"};
List<string> list = myString.ToList();
list.Reverse();
myString = list.ToArray();
Without:
string[] myString = {"a","b","c","d"};
string[] newString = new string[myString.Length];
for (int i = 0, j = myString.Length - 1; i < myString.Length && j >= 0; i++, j--)
{
newString[j] = myString[i];
}
myString = newString;

This is not a complete answer, perhaps an idea..
It is possible to swap two numbers by mathematics
swap(a,b)
a = a + b
b = a - b
a = a - b
Initially I was going to suggest this can be done with character ascii values.. Then I noticed the strings.
Is it acceptable then to
swap(str1, str2)
str1 = str1+str2
str2 = str1[0]
str1 = str1[1]
I hope you get the idea

Have you tried this
string[] myString = { "a", "b", "c", "d","e","f" };
int _firstcounter = 0;
int _lastcounter = myString.Length-1;
while (_firstcounter<=_lastcounter)
{
myString[_firstcounter] += myString[_lastcounter];
myString[_lastcounter] = "" + myString[_firstcounter][0];
myString[_firstcounter] = "" + myString[_firstcounter][1];
_firstcounter++;
_lastcounter--;
}

If the maximum string length is of array is less than 10, then is might be helpful....
string[] myString = { "aaaa", "bbb", "ccccccc", "dddddd", "e", "fffffffff" };
for (int i = 0; i < myString.Length; i++)
{
myString[i] = myString[i].Length.ToString() + myString[i];
}
for (int i = 0; i < myString.Length/2; i++)
{
myString[i] = myString[i] + myString[myString.Length-1-i];
myString[myString.Length - 1 - i] = myString[i];
}
for (int i = 0; i < myString.Length/2; i++)
{
myString[i] = myString[i].Substring(int.Parse(myString[i][0].ToString())+2,int.Parse(myString[i][int.Parse(myString[i][0].ToString())+1].ToString()));
}
for (int i = myString.Length / 2; i < myString.Length; i++)
{
myString[i] = myString[i].Substring(1, int.Parse(myString[i][0].ToString()));
}

Try this.
public static class ExtensionMethods
{
public static IEnumerable<T> ReverseArray<T>(this T[] source)
{
for (int i = source.Length - 1; i >= 0; i--)
{
yield return source[i];
}
}
public static T[] EnumerableToArray<T>(this IEnumerable<T> source)
{
var array = new T[source.Count()];
int k = 0;
foreach (var n in source)
{
array[k++] = n;
}
return array;
}
}
Example usage
public static void Main(string[] args)
{
string[] myString = {"a", "b", "c", "d"};
myString = myString.ReverseArray().EnumerableToArray();
}

static void ReverseMyString(string[] myString)
{
int start=0, end= myString.Length-1;
string temp = "";
while (start < end)
{
temp = myString[start];
myString[start] = myString[end];
myString[end] = temp;
start++;
end--;
}
}

Yes you can do it-
string[] myString = { "a", "b", "c", "d" };
myString = (from a in myString orderby a descending select a).ToArray();

You need at least one variable to swap values.
In pseudo code:
for(i : 0..n/2) {
// swap s[i] and s[n-i]
String tmp = s[i];
s[i] = s[n-i];
s[n-i] = tmp;
}

We Can use Array.Reverse(UrArray);

Check out Array.Reverse method on MSDN.

Related

I am unable to use substring. How can I fix this?

I am trying to see weather the string is in alphabetical order or no and this error pops up
System.ArgumentOutOfRangeException: Index and length must refer to a location within the string.
Parameter name: length
at System.String.Substring(Int32 startIndex, Int32 length)
at Rextester.Program.Main(String[] args)**
public static void Main(string[] args)
{
string str = "bat\ncat\ndog\n";
int c = 0;
for (int i = 0; i < str.Length; i++)
{
if ((str.Substring(i,i + 1).Equals("\n")))
{
c++;
}
}
String[] strArray = new String[c + 1]; //declare with size
int g = 0;
String h = "";
for (int i = 0; i < str.Length; i++)
{
if ((str.Substring(i,i + 1).Equals("\n")))
{
strArray[g] = h;
h = "";
g = g + 1;
}
else
{
h = h + str.Substring(i,i + 1);
}
}
String p = "True";
for (int i = 0; i < g; i++)
{
if (i < (g - 1))
{
String f = strArray[i];
String g2 = strArray[i + 1];
char d = f[0];
char s = g2[0];
int d1 = (int)d;
int s1 = (int)s;
if (d1 > s1)
{
p = "False";
}
}
}
Console.WriteLine(p);
}
}
Not sure about what you are doing in your second loop and why is it so complex. We can do the same like this. Hope this helps.
using System;
public class Program
{
public static void Main()
{
string str = "abcd";
str = str.Replace('\n',' ');
String p = "True";
for (int i = 1; i < str.Length; i++) {
// if element at index 'i' is less
// than the element at index 'i-1'
// then the string is not sorted
if (str[i] < str[i - 1]) {
p = "false";
}
}
Console.WriteLine(p);
}
}
Pay attention to the definition of substring
The substring starts at a specified character position and has a
specified length
Considering your first use of substring, here
for (int i = 0; i < str.Length; i++)
{
if (str.Substring(i, i + 1).Equals("\n"))
{
c++;
}
}
What happens when we get to i=6 here? Substring tries to give you a new string that starts at position i = 6, and is length = 7 characters long. So it tries to give you 7 characters starting from str[6] to str[12]. Well, there is no str[12], so you get an exception.
Its clear that your intent is NOT to get a string that starts at position 6 and is 7 characters long. You want ONE character, so your loop should be this
for (int i = 0; i < str.Length; i++)
{
if (str.Substring(i, 1).Equals("\n"))
{
c++;
}
}
But theres a much simpler way to get your words in alphabetical order using LINQ
string str = "bat\ncat\ndog\n";
//Removes the trailing \n so you don't have one entry that is only whitespace
str = str.Trim();
string[] strSplit = str.Split('\n').OrderBy(x => x[0]).ToArray();
Now all substrings are sorted alphabetically and you can do whatever you want with them

How to get all alphanumeric strings in a range in c#?

How do I get all alpha-number combo's in a given alpha-number combo range using c#?
For getting all numbers in a range I'll do something like below
int x = 10;
int y = 15;
int z=y-x+1;
var range =Enumerable.Range(x,z);
foreach (var element in range)
{
Console.WriteLine(element.ToString()+"-->"+x.ToString()+"-"+y.ToString());
}
Console.ReadLine();
But when the value of x is like 1x and y is like 2b how do I get the range of strings like below?
1x
1y
1z
2a
2b
First, parse the string to get the numerical value and the character. Then, loop for each number from the start to the end. Inside, loop for each character in the alphabet from the start to the current end.
Here you go:
string x = "1x";
string y = "2b";
char startCharacter = x.Substring(x.Length-1)[0];
char endCharacter = y.Substring(y.Length-1)[0];
int startNumber = int.Parse(x.Substring(0, x.Length - 1));
int endNumber = int.Parse(y.Substring(0, y.Length - 1));
var range = new List<string>();
string alphabet = "abcdefghijklmnopqrstuvwxyz";
for(int i = startNumber; i <= endNumber; ++i) {
int currentCharEnd = (i == endNumber) ? alphabet.IndexOf(endCharacter) : alphabet.Length - 1;
for(int j = alphabet.IndexOf(startCharacter); j <= currentCharEnd; ++j) {
range.Add(i.ToString() + alphabet[j]);
}
startCharacter = 'a';
}
// range is now { "1x", "1y", "1z", "2a", "2b" }
You can start by doing this, and extend it to achieve your task fully.
string[] abc = new string[] { "a", "b", "c", "d", "e", "f", "g", "h", "i", "j" };
string x = "1g";
string y = "2b";
string strx = Regex.Match(x, #"\d+").Value;
string stra = Regex.Match(x, #"[a-z]+").Value;
int intx = Int32.Parse(strx);
string stry = Regex.Match(y, #"\d+").Value;
string strb = Regex.Match(x, #"[a-z]+").Value;
int inty = Int32.Parse(stry);
Console.WriteLine(strx);
Console.WriteLine(stra);
Console.WriteLine("----");
int len = inty - intx + 1;
List<string> xycombinations = new List<string>();
string[] ycombinations = new string[] { };
if (len >= 0)
{
int starting = 0;
while (abc[starting] != stra)
{
starting = starting + 1;
}
while (starting < abc.Length)
{
xycombinations.Add(intx.ToString() + abc[starting]);
starting = starting + 1;
}
for (int i = 0; i < xycombinations.Count; i++)
{
Console.WriteLine(xycombinations[i]);
}
}
Console.ReadLine();
It only makes the combination of string x till the end, for instance string x is "1g", so this code makes combinations 1g, 1h, 1i, ij. Similarly you can make combinations of string y by extending. Hope it helps you.

Substring word search produces too much output

I am trying to solve the coding problem below:
Given a dictionary of words
And user entered word to compare against
When comparing the given word against the dictionary
Then output all words in the dictionary that exist in the given word
E.g. StartBurst would output Star and Burst if those words were in the dictionary.
Below is my code:
class Program
{
static void Main(string[] args)
{
Console.WriteLine("Enter a word");
string w = Console.ReadLine();
string[] dictionary = new string[106];
{
string word = w;
string word2 = w;
string w1 = word;
string w2 = word2;
for (int n = 0; n < w.Length; n++)
{
w1 = word;
w2 = word;
for (int x = 0; x < word.Length; x++)
{
for (int i = 0; i < dictionary.Length; i++)
{
if (w1.Equals(dictionary[i]) && w1 != w2)
{
Console.WriteLine(w1);
Console.ReadLine();
}
if (w2.Equals(dictionary[i]) && w1 != w2)
{
Console.WriteLine(w2);
Console.ReadLine();
}
}
w1 = w1.Substring(1, w1.Length - 1);
w2 = word.Substring(0, word.Length - x);
}
word = word.Substring(1, word.Length - 1);
}
}
}
}
}
However, when I run this, it outputs far too much output. For example, if I enter "dontdo" the program outputs "dont do do do do do do". I believe this is due to the word = word.Substring(1, word.Length - 1); statement, but I am unsure how to rectify the situation. Can anyone help?
I created a small code snippet for you to find all the substrings that you need in your search.
void Main()
{
foreach(var w in createMatchables("real"))
{
Console.WriteLine(w);
}
}
// this creates all the searchable substrings from a given string
// all the strings are created from left to right
List<string> createMatchables(string str)
{
var matchList = new List<string>();
for (int i = str.Length; i != 0; i--)
{
var branchCount = str.Length / i;
for (int j = 0; j < branchCount; j++)
{
matchList.Add(str.Substring(i*j, i));
}
}
return matchList;
}

create an array via loop

I need to create an array of strings, easy enough... the only problem is that the strings are integers from 1-1000 and I really dont want to type each of them.
Can you create a loop that could create this?
right now it looks like this
private readonly string[] _myArray = { "1", "2", "3", "4", "5" };
and its called by
for (var i = 0; i < _myArray.Length; i++)
{
arFoo[i].SetBar(_myArray[i]);
}
any suggestions on how to add the other 995 without manually typing them?
This is simple and clean:
readonly string[] _myArray
= Enumerable.Range(1, 1000)
.Select(i => i.ToString())
.ToArray();
If you want to use LINQ:
private readonly string[] _myArray;
public Foo()
{
_myArray = Enumerable.Range(1, 1000).Select(s => s.ToString()).ToArray();
}
Or more traditionally:
public class Foo
{
private readonly string[] _myArray;
public Foo()
{
_myArray = new string[1000];
for(int i=1; i<=1000; i++)
{
_myArray[i - 1] = i.ToString();
}
}
}
How about
int NumberOfElements = 1000;
String[] Array = new String[NumberOfElements];
for(int i=0; i<Array.Length; i++)
{
Array[i] = (i + 1).ToString();
}
Do you need an array? You could just do this:
for (var i = 0; i < 1000; i++)
{
arFoo[i].SetBar(i.ToString());
}
If you do need an array, understand that arrays in C# (and in .Net) are fixed-size. You would need another data structure, like a List<String> in order to add elements, then you can transform to an array (if truly needed) via ToArray().
var array = Enumerable.Range(1, 1000).Select(item => item.ToString()).ToArray();
int[] arr = Enumerable.Range(1, 1000).ToArray();
_myArray = new string[1000];
for (int i = 1; i <= 1000; i++) _myArray[i - 1] = i.ToString();
string[] arr = new string[1000];
for (int i = 1; i <= 1000; i++)
{
arr[i-1] = i.ToString();
}
You can simply do it in a for loop as follows, calling ToString on the int 'i'
private string[] _myArray = new string[1000];
for(int i=0;i<1000;i++)
{
_myArray[i] = i.ToString();
}
private readonly string[] _myArray = new string[1000];
for (int i = 0; i < _myArray.Length; i++)
_myArray[i] = i.ToString();
This is method that will generate array of string from 'from' to 'to' inclusive.
private string[] GetNumbers(int from, int to)
{
int size = to - from + 1;
string[] result = new string[size];
int number = from;
for (int i = 0; i < size; i++)
{
result[i] = number.ToString();
number++;
}
return result;
}
string[] numbers = GetNumbers(1, 1000); // to get what You want

How do I remove duplicates from a C# array?

I have been working with a string[] array in C# that gets returned from a function call. I could possibly cast to a Generic collection, but I was wondering if there was a better way to do it, possibly by using a temp array.
What is the best way to remove duplicates from a C# array?
You could possibly use a LINQ query to do this:
int[] s = { 1, 2, 3, 3, 4};
int[] q = s.Distinct().ToArray();
Here is the HashSet<string> approach:
public static string[] RemoveDuplicates(string[] s)
{
HashSet<string> set = new HashSet<string>(s);
string[] result = new string[set.Count];
set.CopyTo(result);
return result;
}
Unfortunately this solution also requires .NET framework 3.5 or later as HashSet was not added until that version. You could also use array.Distinct(), which is a feature of LINQ.
The following tested and working code will remove duplicates from an array. You must include the System.Collections namespace.
string[] sArray = {"a", "b", "b", "c", "c", "d", "e", "f", "f"};
var sList = new ArrayList();
for (int i = 0; i < sArray.Length; i++) {
if (sList.Contains(sArray[i]) == false) {
sList.Add(sArray[i]);
}
}
var sNew = sList.ToArray();
for (int i = 0; i < sNew.Length; i++) {
Console.Write(sNew[i]);
}
You could wrap this up into a function if you wanted to.
If you needed to sort it, then you could implement a sort that also removes duplicates.
Kills two birds with one stone, then.
This might depend on how much you want to engineer the solution - if the array is never going to be that big and you don't care about sorting the list you might want to try something similar to the following:
public string[] RemoveDuplicates(string[] myList) {
System.Collections.ArrayList newList = new System.Collections.ArrayList();
foreach (string str in myList)
if (!newList.Contains(str))
newList.Add(str);
return (string[])newList.ToArray(typeof(string));
}
List<String> myStringList = new List<string>();
foreach (string s in myStringArray)
{
if (!myStringList.Contains(s))
{
myStringList.Add(s);
}
}
This is O(n^2), which won't matter for a short list which is going to be stuffed into a combo, but could be rapidly be a problem on a big collection.
-- This is Interview Question asked every time. Now i done its coding.
static void Main(string[] args)
{
int[] array = new int[] { 4, 8, 4, 1, 1, 4, 8 };
int numDups = 0, prevIndex = 0;
for (int i = 0; i < array.Length; i++)
{
bool foundDup = false;
for (int j = 0; j < i; j++)
{
if (array[i] == array[j])
{
foundDup = true;
numDups++; // Increment means Count for Duplicate found in array.
break;
}
}
if (foundDup == false)
{
array[prevIndex] = array[i];
prevIndex++;
}
}
// Just Duplicate records replce by zero.
for (int k = 1; k <= numDups; k++)
{
array[array.Length - k] = '\0';
}
Console.WriteLine("Console program for Remove duplicates from array.");
Console.Read();
}
Here is a O(n*n) approach that uses O(1) space.
void removeDuplicates(char* strIn)
{
int numDups = 0, prevIndex = 0;
if(NULL != strIn && *strIn != '\0')
{
int len = strlen(strIn);
for(int i = 0; i < len; i++)
{
bool foundDup = false;
for(int j = 0; j < i; j++)
{
if(strIn[j] == strIn[i])
{
foundDup = true;
numDups++;
break;
}
}
if(foundDup == false)
{
strIn[prevIndex] = strIn[i];
prevIndex++;
}
}
strIn[len-numDups] = '\0';
}
}
The hash/linq approaches above are what you would generally use in real life. However in interviews they usually want to put some constraints e.g. constant space which rules out hash or no internal api - which rules out using LINQ.
protected void Page_Load(object sender, EventArgs e)
{
string a = "a;b;c;d;e;v";
string[] b = a.Split(';');
string[] c = b.Distinct().ToArray();
if (b.Length != c.Length)
{
for (int i = 0; i < b.Length; i++)
{
try
{
if (b[i].ToString() != c[i].ToString())
{
Response.Write("Found duplicate " + b[i].ToString());
return;
}
}
catch (Exception ex)
{
Response.Write("Found duplicate " + b[i].ToString());
return;
}
}
}
else
{
Response.Write("No duplicate ");
}
}
Add all the strings to a dictionary and get the Keys property afterwards. This will produce each unique string, but not necessarily in the same order your original input had them in.
If you require the end result to have the same order as the original input, when you consider the first occurance of each string, use the following algorithm instead:
Have a list (final output) and a dictionary (to check for duplicates)
For each string in the input, check if it exists in the dictionary already
If not, add it both to the dictionary and to the list
At the end, the list contains the first occurance of each unique string.
Make sure you consider things like culture and such when constructing your dictionary, to make sure you handle duplicates with accented letters correctly.
The following piece of code attempts to remove duplicates from an ArrayList though this is not an optimal solution. I was asked this question during an interview to remove duplicates through recursion, and without using a second/temp arraylist:
private void RemoveDuplicate()
{
ArrayList dataArray = new ArrayList(5);
dataArray.Add("1");
dataArray.Add("1");
dataArray.Add("6");
dataArray.Add("6");
dataArray.Add("6");
dataArray.Add("3");
dataArray.Add("6");
dataArray.Add("4");
dataArray.Add("5");
dataArray.Add("4");
dataArray.Add("1");
dataArray.Sort();
GetDistinctArrayList(dataArray, 0);
}
private void GetDistinctArrayList(ArrayList arr, int idx)
{
int count = 0;
if (idx >= arr.Count) return;
string val = arr[idx].ToString();
foreach (String s in arr)
{
if (s.Equals(arr[idx]))
{
count++;
}
}
if (count > 1)
{
arr.Remove(val);
GetDistinctArrayList(arr, idx);
}
else
{
idx += 1;
GetDistinctArrayList(arr, idx);
}
}
Simple solution:
using System.Linq;
...
public static int[] Distinct(int[] handles)
{
return handles.ToList().Distinct().ToArray();
}
Maybe hashset which do not store duplicate elements and silently ignore requests to add
duplicates.
static void Main()
{
string textWithDuplicates = "aaabbcccggg";
Console.WriteLine(textWithDuplicates.Count());
var letters = new HashSet<char>(textWithDuplicates);
Console.WriteLine(letters.Count());
foreach (char c in letters) Console.Write(c);
Console.WriteLine("");
int[] array = new int[] { 12, 1, 1, 1, 1, 1, 1, 1, 2, 2, 2, 2, 2 };
Console.WriteLine(array.Count());
var distinctArray = new HashSet<int>(array);
Console.WriteLine(distinctArray.Count());
foreach (int i in distinctArray) Console.Write(i + ",");
}
NOTE : NOT tested!
string[] test(string[] myStringArray)
{
List<String> myStringList = new List<string>();
foreach (string s in myStringArray)
{
if (!myStringList.Contains(s))
{
myStringList.Add(s);
}
}
return myStringList.ToString();
}
Might do what you need...
EDIT Argh!!! beaten to it by rob by under a minute!
Tested the below & it works. What's cool is that it does a culture sensitive search too
class RemoveDuplicatesInString
{
public static String RemoveDups(String origString)
{
String outString = null;
int readIndex = 0;
CompareInfo ci = CultureInfo.CurrentCulture.CompareInfo;
if(String.IsNullOrEmpty(origString))
{
return outString;
}
foreach (var ch in origString)
{
if (readIndex == 0)
{
outString = String.Concat(ch);
readIndex++;
continue;
}
if (ci.IndexOf(origString, ch.ToString().ToLower(), 0, readIndex) == -1)
{
//Unique char as this char wasn't found earlier.
outString = String.Concat(outString, ch);
}
readIndex++;
}
return outString;
}
static void Main(string[] args)
{
String inputString = "aAbcefc";
String outputString;
outputString = RemoveDups(inputString);
Console.WriteLine(outputString);
}
}
--AptSenSDET
This code 100% remove duplicate values from an array[as I used a[i]].....You can convert it in any OO language..... :)
for(int i=0;i<size;i++)
{
for(int j=i+1;j<size;j++)
{
if(a[i] == a[j])
{
for(int k=j;k<size;k++)
{
a[k]=a[k+1];
}
j--;
size--;
}
}
}
Generic Extension method :
public static IEnumerable<TSource> Distinct<TSource>(this IEnumerable<TSource> source, IEqualityComparer<TSource> comparer)
{
if (source == null)
throw new ArgumentNullException(nameof(source));
HashSet<TSource> set = new HashSet<TSource>(comparer);
foreach (TSource item in source)
{
if (set.Add(item))
{
yield return item;
}
}
}
you can using This code when work with an ArrayList
ArrayList arrayList;
//Add some Members :)
arrayList.Add("ali");
arrayList.Add("hadi");
arrayList.Add("ali");
//Remove duplicates from array
for (int i = 0; i < arrayList.Count; i++)
{
for (int j = i + 1; j < arrayList.Count ; j++)
if (arrayList[i].ToString() == arrayList[j].ToString())
arrayList.Remove(arrayList[j]);
Below is an simple logic in java you traverse elements of array twice and if you see any same element you assign zero to it plus you don't touch the index of element you are comparing.
import java.util.*;
class removeDuplicate{
int [] y ;
public removeDuplicate(int[] array){
y=array;
for(int b=0;b<y.length;b++){
int temp = y[b];
for(int v=0;v<y.length;v++){
if( b!=v && temp==y[v]){
y[v]=0;
}
}
}
}
public static int RemoveDuplicates(ref int[] array)
{
int size = array.Length;
// if 0 or 1, return 0 or 1:
if (size < 2) {
return size;
}
int current = 0;
for (int candidate = 1; candidate < size; ++candidate) {
if (array[current] != array[candidate]) {
array[++current] = array[candidate];
}
}
// index to count conversion:
return ++current;
}
The best way? Hard to say, the HashSet approach looks fast,
but (depending on the data) using a sort algorithm (CountSort ?)
can be much faster.
using System;
using System.Collections.Generic;
using System.Linq;
class Program
{
static void Main()
{
Random r = new Random(0); int[] a, b = new int[1000000];
for (int i = b.Length - 1; i >= 0; i--) b[i] = r.Next(b.Length);
a = new int[b.Length]; Array.Copy(b, a, b.Length);
a = dedup0(a); Console.WriteLine(a.Length);
a = new int[b.Length]; Array.Copy(b, a, b.Length);
var w = System.Diagnostics.Stopwatch.StartNew();
a = dedup0(a); Console.WriteLine(w.Elapsed); Console.Read();
}
static int[] dedup0(int[] a) // 48 ms
{
return new HashSet<int>(a).ToArray();
}
static int[] dedup1(int[] a) // 68 ms
{
Array.Sort(a); int i = 0, j = 1, k = a.Length; if (k < 2) return a;
while (j < k) if (a[i] == a[j]) j++; else a[++i] = a[j++];
Array.Resize(ref a, i + 1); return a;
}
static int[] dedup2(int[] a) // 8 ms
{
var b = new byte[a.Length]; int c = 0;
for (int i = 0; i < a.Length; i++)
if (b[a[i]] == 0) { b[a[i]] = 1; c++; }
a = new int[c];
for (int j = 0, i = 0; i < b.Length; i++) if (b[i] > 0) a[j++] = i;
return a;
}
}
Almost branch free. How? Debug mode, Step Into (F11) with a small array: {1,3,1,1,0}
static int[] dedupf(int[] a) // 4 ms
{
if (a.Length < 2) return a;
var b = new byte[a.Length]; int c = 0, bi, ai, i, j;
for (i = 0; i < a.Length; i++)
{ ai = a[i]; bi = 1 ^ b[ai]; b[ai] |= (byte)bi; c += bi; }
a = new int[c]; i = 0; while (b[i] == 0) i++; a[0] = i++;
for (j = 0; i < b.Length; i++) a[j += bi = b[i]] += bi * i; return a;
}
A solution with two nested loops might take some time,
especially for larger arrays.
static int[] dedup(int[] a)
{
int i, j, k = a.Length - 1;
for (i = 0; i < k; i++)
for (j = i + 1; j <= k; j++) if (a[i] == a[j]) a[j--] = a[k--];
Array.Resize(ref a, k + 1); return a;
}
private static string[] distinct(string[] inputArray)
{
bool alreadyExists;
string[] outputArray = new string[] {};
for (int i = 0; i < inputArray.Length; i++)
{
alreadyExists = false;
for (int j = 0; j < outputArray.Length; j++)
{
if (inputArray[i] == outputArray[j])
alreadyExists = true;
}
if (alreadyExists==false)
{
Array.Resize<string>(ref outputArray, outputArray.Length + 1);
outputArray[outputArray.Length-1] = inputArray[i];
}
}
return outputArray;
}
int size = a.Length;
for (int i = 0; i < size; i++)
{
for (int j = i + 1; j < size; j++)
{
if (a[i] == a[j])
{
for (int k = j; k < size; k++)
{
if (k != size - 1)
{
int temp = a[k];
a[k] = a[k + 1];
a[k + 1] = temp;
}
}
j--;
size--;
}
}
}
So I was doing an interview session and got the same question to sort and distinct
static void Sort()
{
try
{
int[] number = new int[Convert.ToInt32(Console.ReadLine())];
for (int i = 0; i < number.Length; i++)
{
number[i] = Convert.ToInt32(Console.ReadLine());
}
Array.Sort(number);
int[] num = number.Distinct().ToArray();
for (int i = 0; i < num.Length; i++)
{
Console.WriteLine(num[i]);
}
}
catch (Exception ex)
{
Console.WriteLine(ex);
}
Console.Read();
}
using System;
using System.Collections.Generic;
using System.Linq;
namespace Rextester
{
public class Program
{
public static void Main(string[] args)
{
List<int> listofint1 = new List<int> { 4, 8, 4, 1, 1, 4, 8 };
List<int> updatedlist= removeduplicate(listofint1);
foreach(int num in updatedlist)
Console.WriteLine(num);
}
public static List<int> removeduplicate(List<int> listofint)
{
List<int> listofintwithoutduplicate= new List<int>();
foreach(var num in listofint)
{
if(!listofintwithoutduplicate.Any(p=>p==num))
{
listofintwithoutduplicate.Add(num);
}
}
return listofintwithoutduplicate;
}
}
}
strINvalues = "1,1,2,2,3,3,4,4";
strINvalues = string.Join(",", strINvalues .Split(',').Distinct().ToArray());
Debug.Writeline(strINvalues);
Kkk Not sure if this is witchcraft or just beautiful code
1 strINvalues .Split(',').Distinct().ToArray()
2 string.Join(",", XXX);
1 Splitting the array and using Distinct [LINQ] to remove duplicates
2 Joining it back without the duplicates.
Sorry I never read the text on StackOverFlow just the code. it make more sense than the text ;)
Removing duplicate and ignore case sensitive using Distinct & StringComparer.InvariantCultureIgnoreCase
string[] array = new string[] { "A", "a", "b", "B", "a", "C", "c", "C", "A", "1" };
var r = array.Distinct(StringComparer.InvariantCultureIgnoreCase).ToList();
Console.WriteLine(r.Count); // return 4 items
Find answer below.
class Program
{
static void Main(string[] args)
{
var nums = new int[] { 1, 4, 3, 3, 3, 5, 5, 7, 7, 7, 7, 9, 9, 9 };
var result = removeDuplicates(nums);
foreach (var item in result)
{
Console.WriteLine(item);
}
}
static int[] removeDuplicates(int[] nums)
{
nums = nums.ToList().OrderBy(c => c).ToArray();
int j = 1;
int i = 0;
int stop = 0;
while (j < nums.Length)
{
if (nums[i] != nums[j])
{
nums[i + 1] = nums[j];
stop = i + 2;
i++;
}
j++;
}
nums = nums.Take(stop).ToArray();
return nums;
}
}
Just a bit of contribution based on a test i just solved, maybe helpful and open to improvement by other top contributors here.
Here are the things i did:
I used OrderBy which allows me order or sort the items from smallest to the highest using LINQ
I then convert it to back to an array and then re-assign it back to the primary datasource
So i then initialize j which is my right hand side of the array to be 1 and i which is my left hand side of the array to be 0, i also initialize where i would i to stop to be 0.
I used a while loop to increment through the array by going from one position to the other left to right, for each increment the stop position is the current value of i + 2 which i will use later to truncate the duplicates from the array.
I then increment by moving from left to right from the if statement and from right to right outside of the if statement until i iterate through the entire values of the array.
I then pick from the first element to the stop position which becomes the last i index plus 2. that way i am able to remove all the duplicate items from the int array. which is then reassigned.

Categories