Based on the alorithm given here https://en.wikipedia.org/wiki/Gaussian_elimination#Pseudocode,
I tried to implement a C# version of the Gaussian Elimination:
public Matrix GaussianElimination(double epsilon = 1e-10)
{
var result = Copy();
var kMax = Math.Min(result.RowCount, result.ColumnCount);
for (var k = 0; k < kMax; k++)
{
// Find k-th pivot, i.e. maximum in column max
var iMax = result.FindColumnAbsMax(k);
if (Math.Abs(result[iMax, k]) < epsilon)
{
throw new ArithmeticException("Matrix is singular or nearly singular.");
}
// Swap maximum row with current row
SwapRows(k, iMax);
// Make all rows below the current one, with 0 in current column
for (var i = k + 1; i < result.RowCount; i++)
{
var factor = result[i, k] / result[k, k];
for (var j = k + 1; j < result.ColumnCount; j++)
{
result[i, j] = result[i, j] - result[k, j] * factor;
}
result[i, k] = 0;
}
}
return result;
}
It works in most cases (note that this is not performing the back substitution step). However, for the first example given in Wikipedia, the algorithm stop on the singular matrix case and throw the related exception on the row echelon form right before back substitution step with:
public class Program
{
public static void Main(string[] args)
{
var matrix = Matrix.Parse("[1 3 1 9; 1 1 -1 1; 3 11 5 35]");
Console.WriteLine(matrix);
Console.WriteLine(matrix.GaussianElimination());
Console.ReadKey();
}
}
k = 2
kMax = 3
iMax = 2
result = [1 3 1 9; 0 -2 -2 -8; 0 0 0 0]
[EDIT]
The Matrix implementation is a bit lengthy but here is what it is used in regard to the string parsing and the elimination method:
public class Matrix
{
public const string MatrixStart = "[";
public const string MatrixStop = "]";
public const char RowSeparator = ';';
public const char RowCellSeparator = ' ';
public int RowCount { get; }
public int ColumnCount { get; }
public int CellCount => _data.Length;
public bool IsSquare => RowCount == ColumnCount;
public bool IsVector => ColumnCount == 1;
private readonly double[] _data;
public double this[int rowIndex, int columnIndex]
{
get => _data[Convert2DIndexTo1DIndex(rowIndex, columnIndex)];
set => _data[Convert2DIndexTo1DIndex(rowIndex, columnIndex)] = value;
}
public Matrix(Matrix matrix)
: this(matrix.RowCount, matrix.ColumnCount)
{
for (var i = 0; i < _data.Length; i++)
{
_data[i] = matrix._data[i];
}
}
public Matrix(int size, double placeHolder = 0)
: this(size, size, placeHolder)
{
}
public Matrix(int rowCount, int columnCount, double initializationValue = 0)
{
if (rowCount < 0)
{
throw new ArgumentOutOfRangeException(nameof(rowCount));
}
if (columnCount < 0)
{
throw new ArgumentOutOfRangeException(nameof(columnCount));
}
RowCount = rowCount;
ColumnCount = columnCount;
_data = new double[RowCount * ColumnCount];
if (Math.Abs(initializationValue) > 0)
{
Set(initializationValue);
}
}
public Matrix(int rowCount, int columnCount, double[] initializationValues)
{
if (rowCount < 0)
{
throw new ArgumentOutOfRangeException(nameof(rowCount));
}
if (columnCount < 0)
{
throw new ArgumentOutOfRangeException(nameof(columnCount));
}
if (initializationValues.Length != rowCount * columnCount)
{
throw new ArgumentOutOfRangeException(nameof(initializationValues));
}
RowCount = rowCount;
ColumnCount = columnCount;
_data = new double[initializationValues.Length];
initializationValues.CopyTo(_data, 0);
}
private int Convert2DIndexTo1DIndex(int rowIndex, int columnIndex)
{
return rowIndex * ColumnCount + columnIndex;
}
public void Set(double value)
{
for (var i = 0; i < _data.Length; i++)
{
_data[i] = value;
}
}
public Matrix Transpose()
{
var result = new Matrix(ColumnCount, RowCount);
for (var i = 0; i < result.RowCount; i++)
{
for (var j = 0; j < result.ColumnCount; j++)
{
result[i, j] = this[j, i];
}
}
return result;
}
public Matrix Copy()
{
return new Matrix(this);
}
private int FindColumnAbsMax(int index)
{
return FindColumnAbsMax(index, index);
}
private int FindColumnAbsMax(int rowStartIndex, int columnIndex)
{
var maxIndex = rowStartIndex;
for (var i = rowStartIndex + 1; i < RowCount; i++)
{
if (Math.Abs(this[maxIndex, columnIndex]) <= Math.Abs(this[i, columnIndex]))
{
maxIndex = i;
}
}
return maxIndex;
}
public void SwapRows(int rowIndexA, int rowIndexB)
{
for (var j = 0; j < ColumnCount; j++)
{
var indexA = Convert2DIndexTo1DIndex(rowIndexA, j);
var indexB = Convert2DIndexTo1DIndex(rowIndexB, j);
_data.Swap(indexA, indexB);
}
}
public void SwapColumns(int columnIndexA, int columnIndexB)
{
for (var i = 0; i < RowCount; i++)
{
var indexA = Convert2DIndexTo1DIndex(i, columnIndexA);
var indexB = Convert2DIndexTo1DIndex(i, columnIndexB);
_data.Swap(indexA, indexB);
}
}
public static Matrix Parse(string matrixString)
{
if (!matrixString.StartsWith(MatrixStart) || !matrixString.EndsWith(MatrixStop))
{
throw new FormatException();
}
matrixString = matrixString.Remove(0, 1);
matrixString = matrixString.Remove(matrixString.Length - 1, 1);
var rows = matrixString.Split(new[] { RowSeparator }, StringSplitOptions.RemoveEmptyEntries);
if (rows.Length <= 0)
{
return new Matrix(0, 0);
}
var cells = ParseRow(rows[0]);
var matrix = new Matrix(rows.Length, cells.Length);
for (var j = 0; j < cells.Length; j++)
{
matrix[0, j] = cells[j];
}
for (var i = 1; i < matrix.RowCount; i++)
{
cells = ParseRow(rows[i]);
for (var j = 0; j < cells.Length; j++)
{
matrix[i, j] = cells[j];
}
}
return matrix;
}
private static double[] ParseRow(string row)
{
var cells = row.Split(new [] { RowCellSeparator }, StringSplitOptions.RemoveEmptyEntries);
return cells.Select(x => Convert.ToDouble(x.Replace(" ", string.Empty))).ToArray();
}
}
And the 1D Array extension for swapping two items:
public static class ArrayHelpers
{
public static void Swap<TSource>(this TSource[] source, int indexA, int indexB)
{
var tmp = source[indexA];
source[indexA] = source[indexB];
source[indexB] = tmp;
}
}
Related
I am trying to make a Sudoku solver. Whenever I try to run it it gives me a Stack Overflow Error:
System.StackOverflowException: 'Exception of type 'System.StackOverflowException' was thrown.'
I believe that it probably has to do with the solve function calling on the FindEmpy function too much?
Any help is greatly appreciated!
Thanks so much!
using System;
namespace sudokusolver
{
class Program
{
static public void PrintBoard(int[][] bo)
{
for (int i = 0; i < bo.Length; i++)
{
if (i % 3 == 0 && i != 0)
{
Console.WriteLine("- - - - - - - - - - - - -");
}
for (int j = 0; j < bo[0].Length; j++)
{
if (j % 3 == 0 && j != 0)
{
Console.Write(" | ");
}
if (j == 8)
{
Console.WriteLine(bo[i][j]);
}
else
{
Console.Write(bo[i][j] + " ");
}
}
}
}
static public (int,int) FindEmpty(int[][] bo)
{
for (int i = 0; i < bo.Length; i++)
{
for (int j = 0; j < bo[0].Length; j++)
{
if (bo[i][j] == 0)
{
return (i, j);
}
}
}
return (100, 100);
}
static public bool Solve(int[][] bo)
{
int x;
int y;
if (FindEmpty(bo) == (100, 100))
{
return true;
}
else
{
y = FindEmpty(bo).Item1;
x = FindEmpty(bo).Item2;
}
for (int i = 0; i < 10; i++)
{
if (IsValid(bo, i, x, y) == true)
{
bo[y][x] = i;
if (Solve(bo) == true)
{
return true;
}
else
{
bo[y][x] = 0;
}
}
}
return false;
}
static public bool IsValid(int[][] bo, int num, int x, int y)
{
for (int i = 0; i < bo.Length; i++)
{
if (bo[y][i] == num && x != i)
{
return false;
}
}
for (int i = 0; i < bo[0].Length; i++)
{
if (bo[i][x] == num && y != i)
{
return false;
}
}
int boxx = x / 3;
int boxy = y / 3;
for (int i = boxy * 3; i < boxy * 3 + 3; i++)
{
for (int j = boxx * 3; j < boxx * 3 + 3; j++)
{
if (bo[i][j] == num && i != y && j != x)
{
return false;
}
}
}
return true;
}
static void Main(string[] args)
{
int[][] board = {
new int[] {7,0,0,0,0,0,2,0,0},
new int[] {4,0,2,0,0,0,0,0,3},
new int[] {0,0,0,2,0,1,0,0,0},
new int[] {3,0,0,1,8,0,0,9,7},
new int[] {0,0,9,0,7,0,6,0,0},
new int[] {6,5,0,0,3,2,0,0,1},
new int[] {0,0,0,4,0,9,0,0,0},
new int[] {5,0,0,0,0,0,1,0,6},
new int[] {0,0,6,0,0,0,0,0,8}
};
PrintBoard(board);
Solve(board);
PrintBoard(board);
}
}
}
static public bool Solve(int[][] bo)
{
int x;
int y;
if (FindEmpty(bo) == (100, 100))
{
return true;
}
else
{
y = FindEmpty(bo).Item1;
x = FindEmpty(bo).Item2;
}
- for (int i = 0; i < 10; i++)
+ for (int i = 1; i < 10; i++)
{
if (IsValid(bo, i, x, y) == true)
{
bo[y][x] = i;
if (Solve(bo) == true)
{
return true;
}
else
{
bo[y][x] = 0;
}
}
}
return false;
}
At some point IsValid(bo, 0, x, y) returns true, so you replace the zero with another zero forever.
I need to convert n array (dimension is not known) to 1d and revert it back to nd array.
I loop through the whole array and add elements to 1d to convert, but I don't know how to revert it back.
public class ArrayND<T>
{
private int[] _lengths;
private Array _array;
public ArrayND(int[] length)
{
_lengths = length;
_array = Array.CreateInstance(typeof (T), _lengths);
}
}
///Loop through
public float[] ConvertTo1D(ArrayND<float> ndArray)
{
float[] OneDArray = new float[ndArray.Values.Length];
System.Collections.IEnumerator myEnumerator = ndArray.Values.GetEnumerator();
int cols = ndArray.Values.GetLength(ndArray.Values.Rank - 1);
int j = 0;
while (myEnumerator.MoveNext())
{
OneDArray[j] = (float)myEnumerator.Current;
j++;
}
return OneDArray;
}
public class ArrayND<T>
{
private int[] _lengths;
private Array _array;
public ArrayND(int[] length)
{
_lengths = length;
_array = Array.CreateInstance(typeof(T), _lengths);
}
public T GetValue(int[] index) => (T)_array.GetValue(index);
public void SetValue(T value, int[] index) => _array.SetValue(value, index);
public T[] ToOneD() => _array.Cast<T>().ToArray();
public static ArrayND<T> FromOneD(T[] array, int[] lengths)
{
if (array.Length != lengths.Aggregate((i, j) => i * j))
throw new ArgumentException("Number of elements in source and destination arrays does not match.");
var factors = lengths.Select((item, index) => lengths.Skip(index).Aggregate((i, j) => i * j)).ToArray();
var factorsHelper = factors.Zip(factors.Skip(1).Append(1), (Current, Next) => new { Current, Next }).ToArray();
var res = new ArrayND<T>(lengths);
for (var i = 0; i < array.Length; i++)
res.SetValue(array[i],
factorsHelper.Select(item => i % item.Current / item.Next).ToArray());
return res;
}
public override bool Equals(object obj) =>
(obj is ArrayND<T> ndArray) &&
_lengths.SequenceEqual(ndArray._lengths) &&
_array.Cast<T>().SequenceEqual(ndArray._array.Cast<T>());
public override int GetHashCode() =>
new[] { 17 }
.Concat(_lengths.Select(i => i.GetHashCode()))
.Concat(_array.Cast<T>().Select(i => i.GetHashCode()))
.Aggregate((i, j) => unchecked(23 * i + j));
}
It works with any number of dimensions.
Test it:
int I = 2, J = 3, K = 4;
var a = new ArrayND<int>(new[] { I, J, K });
var v = 0;
for (var i = 0; i < I; i++)
for (var j = 0; j < J; j++)
for (var k = 0; k < K; k++)
a.SetValue(++v, new[] { i, j, k });
var b = a.ToOneD();
var c = ArrayND<int>.FromOneD(b, new[] { I, J, K });
Console.WriteLine(a.Equals(c)); // True
or:
int I = 2, J = 3;
var a = new ArrayND<int>(new[] { I, J });
var v = 0;
for (var i = 0; i < I; i++)
for (var j = 0; j < J; j++)
a.SetValue(++v, new[] { i, j });
var b = a.ToOneD();
var c = ArrayND<int>.FromOneD(b, new[] { I, J });
Console.WriteLine(a.Equals(c)); // True
or:
int I = 2, J = 3, K = 4, M = 5;
var a = new ArrayND<int>(new[] { I, J, K, M });
var v = 0;
for (var i = 0; i < I; i++)
for (var j = 0; j < J; j++)
for (var k = 0; k < K; k++)
for (var m = 0; m < M; m++)
a.SetValue(++v, new[] { i, j, k, m });
var b = a.ToOneD();
var c = ArrayND<int>.FromOneD(b, new[] { I, J, K, M });
Console.WriteLine(a.Equals(c)); // True
Well, I solve it in a weird way. I am open to better approaches
public ArrayND<string> convert1DtoND(string[] oneDarray, int[] dimension)
{
ArrayND<string> ndArray = new ArrayND<string>(dimension);
int[] index = new int[ndArray.Values.Rank];
int[] length = new int[ndArray.Values.Rank];
int j = 0;
for (int i = 0; i < length.Length; i++)
{
length[i] = ndArray.Values.GetLength(i);
}
do
{
ndArray[index] = oneDarray[j];
j++;
} while (Increment(index, length));
return ndArray;
}
public static bool Increment(int[] index, int[] length)
{
int i = index.Length - 1;
index[i]++;
while (i >= 0 && index[i] == length[i] && length[i] > 0)
{
index[i--] = 0;
if (i >= 0)
index[i]++;
}
if (i < 0 || length[i] == 0)
return false;
else
return true;
}
I'm trying to implement the MinMax algorithm for four in a row (or connect4 or connect four) game.
I think I got the idea of it, it should build a tree of possible boards up to a certain depth, evaluate them and return their score, then we just take the max of those scores.
So, aiChooseCol() checks the score of every possible column by calling MinMax() and returns the column with the max score.
Now I wasn't sure, is this the right way to call MinMax()?
Is it right to check temp = Math.Max(temp, 1000);?
I still haven't made the heuristic function but this should at least recognize a winning column and choose it, but currently it just choose the first free column from the left... I can't figure out what am I doing wrong.
private int AiChooseCol()
{
int best = -1000;
int col=0;
for (int i = 0; i < m_Board.Cols; i++)
{
if (m_Board.CheckIfColHasRoom(i))
{
m_Board.FillSignInBoardAccordingToCol(i, m_Sign);
int t = MinMax(5, m_Board, board.GetOtherPlayerSign(m_Sign));
if (t > best)
{
best = t;
col = i;
}
m_Board.RemoveTopCoinFromCol(i);
}
}
return col;
}
private int MinMax(int Depth, board Board, char PlayerSign)
{
int temp=0;
if (Depth <= 0)
{
// return from heurisitic function
return temp;
}
char otherPlayerSign = board.GetOtherPlayerSign(PlayerSign);
char checkBoard = Board.CheckBoardForWin();
if (checkBoard == PlayerSign)
{
return 1000;
}
else if (checkBoard == otherPlayerSign)
{
return -1000;
}
else if (!Board.CheckIfBoardIsNotFull())
{
return 0; // tie
}
if (PlayerSign == m_Sign) // maximizing Player is myself
{
temp = -1000;
for (int i = 0; i < Board.Cols; i++)
{
if (Board.FillSignInBoardAccordingToCol(i, PlayerSign)) // so we don't open another branch in a full column
{
var v = MinMax(Depth - 1, Board, otherPlayerSign);
temp = Math.Max(temp, v);
Board.RemoveTopCoinFromCol(i);
}
}
}
else
{
temp = 1000;
for (int i = 0; i < Board.Cols; i++)
{
if (Board.FillSignInBoardAccordingToCol(i, PlayerSign)) // so we don't open another branch in a full column
{
var v = MinMax(Depth - 1, Board, otherPlayerSign);
temp = Math.Min(temp, v);
Board.RemoveTopCoinFromCol(i);
}
}
}
return temp;
}
Some notes:
FillSignInBoardAccordingToCol() returns a boolean if it was successful.
The board type has a char[,] array with the actual board and signs of the players.
This code is in the AI Player class.
So I decided to write my own MinMax Connect 4. I used the depth to determine the value of a win or loss so that a move that gets you closer to winning or blocking a loss will take precedence. I also decide that I will randomly pick the move if more than one has the same heuristic. Finally I stretched out the depth to 6 as that's how many moves are required to find possible win paths from the start.
private static void Main(string[] args)
{
var board = new Board(8,7);
var random = new Random();
while (true)
{
Console.WriteLine("Pick a column 1 -8");
int move;
if (!int.TryParse(Console.ReadLine(), out move) || move < 1 || move > 8)
{
Console.WriteLine("Must enter a number 1-8.");
continue;
}
if (!board.DropCoin(1, move-1))
{
Console.WriteLine("That column is full, pick another one");
continue;
}
if (board.Winner == 1)
{
Console.WriteLine(board);
Console.WriteLine("You win!");
break;
}
if (board.IsFull)
{
Console.WriteLine(board);
Console.WriteLine("Tie!");
break;
}
var moves = new List<Tuple<int, int>>();
for (int i = 0; i < board.Columns; i++)
{
if (!board.DropCoin(2, i))
continue;
moves.Add(Tuple.Create(i, MinMax(6, board, false)));
board.RemoveTopCoin(i);
}
int maxMoveScore = moves.Max(t => t.Item2);
var bestMoves = moves.Where(t => t.Item2 == maxMoveScore).ToList();
board.DropCoin(2, bestMoves[random.Next(0,bestMoves.Count)].Item1);
Console.WriteLine(board);
if (board.Winner == 2)
{
Console.WriteLine("You lost!");
break;
}
if (board.IsFull)
{
Console.WriteLine("Tie!");
break;
}
}
Console.WriteLine("DONE");
Console.ReadKey();
}
private static int MinMax(int depth, Board board, bool maximizingPlayer)
{
if (depth <= 0)
return 0;
var winner = board.Winner;
if (winner == 2)
return depth;
if (winner == 1)
return -depth;
if (board.IsFull)
return 0;
int bestValue = maximizingPlayer ? -1 : 1;
for (int i = 0; i < board.Columns; i++)
{
if (!board.DropCoin(maximizingPlayer ? 2 : 1, i))
continue;
int v = MinMax(depth - 1, board, !maximizingPlayer);
bestValue = maximizingPlayer ? Math.Max(bestValue, v) : Math.Min(bestValue, v);
board.RemoveTopCoin(i);
}
return bestValue;
}
public class Board
{
private readonly int?[,] _board;
private int? _winner;
private bool _changed;
public Board(int cols, int rows)
{
Columns = cols;
Rows = rows;
_board = new int?[cols, rows];
}
public int Columns { get; }
public int Rows { get; }
public bool ColumnFree(int column)
{
return !_board[column, 0].HasValue;
}
public bool DropCoin(int playerId, int column)
{
int row = 0;
while (row < Rows && !_board[column,row].HasValue)
{
row++;
}
if (row == 0)
return false;
_board[column, row - 1] = playerId;
_changed = true;
return true;
}
public bool RemoveTopCoin(int column)
{
int row = 0;
while (row < Rows && !_board[column, row].HasValue)
{
row++;
}
if (row == Rows)
return false;
_board[column, row] = null;
_changed = true;
return true;
}
public int? Winner
{
get
{
if (!_changed)
return _winner;
_changed = false;
for (int i = 0; i < Columns; i++)
{
for (int j = 0; j < Rows; j++)
{
if (!_board[i, j].HasValue)
continue;
bool horizontal = i + 3 < Columns;
bool vertical = j + 3 < Rows;
if (!horizontal && !vertical)
continue;
bool forwardDiagonal = horizontal && vertical;
bool backwardDiagonal = vertical && i - 3 >= 0;
for (int k = 1; k < 4; k++)
{
horizontal = horizontal && _board[i, j] == _board[i + k, j];
vertical = vertical && _board[i, j] == _board[i, j + k];
forwardDiagonal = forwardDiagonal && _board[i, j] == _board[i + k, j + k];
backwardDiagonal = backwardDiagonal && _board[i, j] == _board[i - k, j + k];
if (!horizontal && !vertical && !forwardDiagonal && !backwardDiagonal)
break;
}
if (horizontal || vertical || forwardDiagonal || backwardDiagonal)
{
_winner = _board[i, j];
return _winner;
}
}
}
_winner = null;
return _winner;
}
}
public bool IsFull
{
get
{
for (int i = 0; i < Columns; i++)
{
if (!_board[i, 0].HasValue)
return false;
}
return true;
}
}
public override string ToString()
{
var builder = new StringBuilder();
for (int j = 0; j < Rows; j++)
{
builder.Append('|');
for (int i = 0; i < Columns; i++)
{
builder.Append(_board[i, j].HasValue ? _board[i,j].Value.ToString() : " ").Append('|');
}
builder.AppendLine();
}
return builder.ToString();
}
}
I trying to do sorting without use of any method or function
My Code :
string[] names = { "Flag", "Nest", "Cup", "Burg", "Yatch", "Next" };
string name = string.Empty;
Console.WriteLine("Sorted Strings : ");
for (int i = 0; i < names.Length; i++)
{
for (int j = i + 1; j < names.Length; j++)
{
for (int c = 0; c < names.Length; c++)
{
if (names[i][c] > names[j][c])
{
name = names[i];
names[i] = names[j];
names[j] = name;
}
}
}
Console.WriteLine(names[i]);
}
Please let me bring any solution for this code ?
In this code i am getting "Index was outside the bounds of the array" exception
int temp = 0;
int[] arr = new int[] { 20, 65, 98, 71, 64, 11, 2, 80, 5, 6, 100, 50, 13, 9, 80, 454 };
for (int i = 0; i < arr.Length; i++)
{
for (int j = i + 1; j < arr.Length; j++)
{
if (arr[i] > arr[j])
{
temp = arr[j];
arr[j] = arr[i];
arr[i] = temp;
}
}
Console.WriteLine(arr[i]);
}
Console.ReadKey();
You need to implement a sorting algorithm.
A very simple algorithm you can implement is the insertion sort:
string[] names = { "Flag", "Nest", "Cup", "Burg", "Yatch", "Next" };
for (int i = 0; i < names.Length; i++)
{
var x = names[i];
var j = i;
while(j > 0 && names[j-1].CompareTo(x) > 0)
{
names[j] = names[j-1];
j = j-1;
}
names[j] = x;
}
string[] names = { "Flag", "Next", "Cup", "Burg", "Yatch", "Nest" };
string name = string.Empty;
Console.WriteLine("Sorted Strings : ");
for (int i = 0; i < names.Length; i++)
{
int c = 0;
for (int j = 1; j < names.Length; j++)
{
if (j > i)
{
Sort:
if (names[i][c] != names[j][c])
{
if (names[i][c] > names[j][c])
{
name = names[i];
names[i] = names[j];
names[j] = name;
}
}
else
{
c = c + 1;
goto Sort;
}
}
}
Console.WriteLine(names[i]);
}
I you were conflicting in length of names array and comparing string. Below is the working solution . I have tested it it's working now
static void Main(string[] args)
{
int min=0;
string[] names = { "Flag", "Nest", "Cup", "Burg", "Yatch", "Next" };
string name = string.Empty;
Console.WriteLine("Sorted Strings : ");
for (int i = 0; i < names.Length-1; i++)
{
for (int j = i + 1; j < names.Length;j++ )
{
if(names[i].Length < names[j].Length)
min =names[i].Length;
else
min =names[j].Length;
for(int k=0; k<min;k++)
{
if (names[i][k] > names[j][k])
{
name = names[i].ToString();
names[i] = names[j];
names[j] = name;
break;
}
else if(names[i][k] == names[j][k])
{
continue;
}
else
{
break;
}
}
}
}
for(int i= 0;i<names.Length;i++)
{
Console.WriteLine(names[i]);
Console.ReadLine();
}
}
}
class Program
{
static void Main(string[] args)
{
int[] arr = new int[] {9,1,6,3,7,2,4};
int temp = 0;
for (int i = 0; i < arr.Length; i++)
{
for (int j = i + 1; j < arr.Length;j++)
{
if(arr[i]>arr[j])
{
temp = arr[j];
arr[j] = arr[i];
arr[i] = temp;
}
}
Console.Write(arr[i]+",");
}
Console.ReadLine();
}
for (int i = 0; i < names.Length; i++)
{
string temp = "";
for (int j = i + 1; j < names.Length; j++)
{
if (names[i].CompareTo(names[j]) > 0)
{
temp = names[j];
names[j] = names[i];
names[i] = temp;
}
}
}
public int compareing(string a, string b)
{
char[] one = a.ToLower().ToCharArray();
char[] two = b.ToLower().ToCharArray();
int ret = 0;
for (int i = 0; i < one.Length; i++)
{
for (int j = 0; j < two.Length; j++)
{
Loop:
int val = 0;
int val2 = 0;
string c = one[i].ToString();
char[] c1 = c.ToCharArray();
byte[] b1 = ASCIIEncoding.ASCII.GetBytes(c1);
string A = two[j].ToString();
char[] a1 = A.ToCharArray();
byte[] d1 = ASCIIEncoding.ASCII.GetBytes(a1);
int sec = d1[0];
int fir = b1[0];
if (fir > sec)
{
return ret = 1;
break;
}
else
{
if (fir == sec)
{
j = j + 1;
i = i + 1;
if (one.Length == i)
{
return ret = 0;
}
goto Loop;
}
else
{
return 0;
}
}
}
}
return ret;
}
public void stringcomparision(List<string> li)
{
string temp = "";
for(int i=0;i<li.Count;i++)
{
for(int j=i+1;j<li.Count;j++)
{
if(compareing(li[i],li[j])>0)
{
//if grater than it throw 1 else -1
temp = li[j];
li[j] = li[i];
li[i] = temp;
}
}
}
Console.WriteLine(li);
}
for (int i = 0; i < names.Length - 1; i++)
{
string temp = string.Empty;
for (int j = i + 1; j < names.Length; j++)
{
if (names[i][0] > names[j][0])
{
temp = names[i].ToString();
names[i] = names[j].ToString();
names[j] = temp;
}
}
}
for (int i = 0; i < names.Length - 1; i++)
{
int l = 0;
if (names[i][0] == names[i + 1][0])
{
string temp = string.Empty;
if (names[i].Length > names[i + 1].Length)
l = names[i + 1].Length;
else
l = names[i].Length;
for (int j = 0; j < l; j++)
{
if (names[i][j] != names[i + 1][j])
{
if (names[i][j] > names[i + 1][j])
{
temp = names[i].ToString();
names[i] = names[i + 1].ToString();
names[i + 1] = temp;
}
break;
}
}
}
}
foreach (var item in names)
{
Console.WriteLine(item.ToString());
}
string[] names = { "Flag", "Nest", "Cup", "Burg", "Yatch", "Next" };
string temp = "";
int tempX = 0, tempY = 0;
int tempX1 = 0, tempY1 = 0;
for (int i = 0; i<names.Length; i++)
{
for (int j = i+1; j<names.Length; j++)
{
if (((string)names[i])[0] > ((string)names[j])[0])
{
temp=(string)names[i];
names[i]=names[j];
names[j]=temp;
}
else if (((string)names[i])[0] == ((string)names[j])[0])
{
tempX=0; tempY=0;
tempX1=names[i].Length;
tempY1=names[j].Length;
while (tempX1 > 0 && tempY1 >0)
{
if (((string)names[i])[tempX] !=((string)names[j])[tempY])
{
if (((string)names[i])[tempX]>((string)names[j])[tempY])
{
temp=(string)names[i];
names[i]=names[j];
names[j]=temp;
break;
}
}
tempX++;
tempY++;
tempX1--;
tempY1--;
}
}
}
}
You can do it using bubble sort:
Assume you have the array of names called name
The tempName is just to not change the original array (You can use the original array instead)
void sortStudentsAlphabetically()
{
int nameIndex;
string temp;
string[] tempName = name;
bool swapped = true;
for(int i = 0; i < name.Length-1 && swapped ; i++)
{
swapped = false;
for(int j = 0; j < name.Length-1; j++)
{
nameIndex = 0;
recheck:
if (name[j][nameIndex]> name[j+1][nameIndex])
{
temp = tempName[j];
tempName[j] = tempName[j+1];
tempName[j+1] = temp;
swapped = true;
}
if (name[j][nameIndex] == name[j + 1][nameIndex])
{
nameIndex++;
goto recheck;
}
}
}
foreach(string x in tempName)
{
Console.WriteLine(x);
}
}
User Below code :
int[] arrayList = new int[] {2,9,4,3,5,1,7};
int temp = 0;
for (int i = 0; i <= arrayList.Length-1; i++)
{
for (int j = i+1; j < arrayList.Length; j++)
{
if (arrayList[i] > arrayList[j])
{
temp = arrayList[i];
arrayList[i] = arrayList[j];
arrayList[j] = temp;
}
}
}
Console.WriteLine("Sorting array in ascending order : ");
foreach (var item in arrayList)
{
Console.WriteLine(item);
}
Console.ReadLine();
Output:
Sorting array in ascending order : 1 2 3 4 5 7 9
I am using OpenOffice uno api to iterate through all text in writer document. To iterate over text tables currently I am using XTextTable interface getCellNames() method. How I could detect merged and split cells. I want to export table to html, so I should calculate colspan and rowspan.
I would appreciate any suggestions... I am out of ideas :(
Finally I have the answer (actually colspan part of it). This code is ugly I know, but one day I'll refactor it ;)
public class Cell
{
private List<string> _text = new List<string>();
public List<string> Text
{
get { return _text; }
set { _text = value; }
}
public int ColSpan { get; set; }
public int RowSpan { get; set; }
public Cell(int colSpan, int rowSpan, List<string> text)
{
ColSpan = colSpan;
RowSpan = rowSpan;
_text = text;
}
public Cell(int colSpan, int rowSpan)
{
ColSpan = colSpan;
RowSpan = rowSpan;
}
}
and here it is table parse method
public static List<List<Cell>> ParseTable(XTextTable table)
{
XTableRows rows = table.getRows() as XTableRows;
int rowCount = rows.getCount();
int sum = GetTableColumnRelativeSum(table);
// Temprorary store for column count of each row
int[] colCounts = new int[rowCount];
List<List<int>> matrix = new List<List<int>>(rowCount);
for (int i = 0; i < rowCount; i++)
matrix.Add(new List<int>());
// Get column count for each row
int maxColCount = 0;
for (int rowNo = 0; rowNo < rowCount; rowNo++)
{
TableColumnSeparator[] sep = GetTableRowSeperators(rows, rowNo);
colCounts[rowNo] = sep.Length + 1;
if (maxColCount < colCounts[rowNo])
maxColCount = colCounts[rowNo];
for (int j = 0; j < sep.Length; j++)
matrix[rowNo].Add(sep[j].Position);
matrix[rowNo].Add(sum);
}
int[] curIndex = new int[rowCount];
List<List<Cell>> results = new List<List<Cell>>(rowCount);
for (int i = 0; i < rowCount; i++)
results.Add(new List<Cell>());
int curMinSep = matrix[0][0];
do
{
curMinSep = matrix[0][curIndex[0]];
for (int i = 0; i < rowCount; i++)
if (curMinSep > matrix[i][curIndex[i]]) curMinSep = matrix[i][curIndex[i]];
for (int rowNo = 0; rowNo < rowCount; rowNo++)
{
int col = curIndex[rowNo];
int lastIdx = results[rowNo].Count - 1;
if (curMinSep == matrix[rowNo][col])
{
if (colCounts[rowNo] > col + 1) curIndex[rowNo] = col + 1;
if (results[rowNo].Count > 0 &&
results[rowNo][lastIdx].Text.Count < 1 &&
results[rowNo][lastIdx].ColSpan > 0)
{
results[rowNo][lastIdx].ColSpan++;
results[rowNo][lastIdx].Text = GetCellText(table, rowNo, col);
}
else
{
results[rowNo].Add(new Cell(0, 0, GetCellText(table, rowNo, col)));
}
}
else
{
if (results[rowNo].Count > 0 &&
results[rowNo][lastIdx].Text.Count < 1)
{
results[rowNo][lastIdx].ColSpan++;
}
else
{
results[rowNo].Add(new Cell(1, 0));
}
}
}
} while (curMinSep < sum);
return results;
}
public static short GetTableColumnRelativeSum(XTextTable rows)
{
XPropertySet xPropertySet = rows as XPropertySet;
short sum = (short)xPropertySet.getPropertyValue("TableColumnRelativeSum").Value;
return sum;
}
public static TableColumnSeparator[] GetTableRowSeperators(XTableRows rows, int rowNo)
{
XPropertySet rowProperties = rows.getByIndex(rowNo).Value as XPropertySet;
TableColumnSeparator[] sep = null;
sep = rowProperties.getPropertyValue("TableColumnSeparators").Value as TableColumnSeparator[];
return sep;
}