Пропустить первую строку в матрице и проверить ширину / высоту - PullRequest
1 голос
/ 20 августа 2010

У меня есть матрица в этом формате, которую я пытаюсь проверить и удалить первую строку:

3 4 
0 0 0 
0 0 0
0 0 0
0 0 0

Где первая строка, а остальные строки - фактические данные.

Width Height

Как лучше всего удалить первую строку, а B проверить, что все строки соответствуют указанным критериям ширины и высоты?Я мог бы сделать простой цикл и скопировать их, но я ищу более элегантный способ сделать это?Может быть, с помощью Linq или одного из методов сбора?

Пока у меня есть:

 //add the split for correctness 
 string[][] lines = File.ReadAllLines(fileName).Select(x=>x.Split(' ')).ToArray();
 //first line is width/hight
 int length  = lines.Length ==0 ;
 if(|| (length > 0 && lines[0].Length !=2 ) ){
     throw new InvalidDataException("File is not correctly formated:" + fileName);
 }

 int width = lines[0][0];
 int hieght = lines[0][1];

 //Check Row count       
 if(length != height -1){
   throw new InvalidDataException("Invalid missing rows in the Matrix definition");
 }

 //make sure the file is correctly formated with width and height:    
 if(lines.Any(x=>x.Length != Width)){
     //I know this fails because of first line
     throw new InvalidDataException("Invalid Width in a row in the Matrix");
 }

Есть предложения по улучшению способа проверки ввода?

Ответы [ 3 ]

2 голосов
/ 20 августа 2010
string[][] lines = File.ReadAllLines(fileName)
  .Select(line => line.Split(' ')).ToArray();
if (lines[0].Length != 2)
  throw new SomeException();

int width = int.Parse(lines[0][0]);
int height = int.Parse(lines[0][1]);

int[][] matrix = lines.Skip(1)
  .Select(line => line.Select(n => int.Parse(n)).ToArray())
  .ToArray();

if (matrix.Length != height || matrix.Any(line => line.Length != width))
  throw new SomeException();
1 голос
/ 20 августа 2010

sscanf было бы неплохо, но я сделал это с рег.эксп.и он проверит, являются ли ширина и высота целыми числами, а также проверит каждое следующее число на предмет целочисленности:

static bool isValid(string path)
{
    var data = File.ReadAllText(path);

    var first = Regex.Match(data, @"\A *(\d+) +(\d+) *([\r\n|\n]|\Z)");

    if (!first.Success) return false;

    int width = int.Parse(first.Groups[1].Value);
    int height = int.Parse(first.Groups[2].Value);

    return Regex.Match(data, @"\A *\d+ +\d+ *((\r\n|\n)((^ *| +)\d+){" + width + @"} *){" + height + @"}\Z", RegexOptions.Multiline).Success;
}

Я могу сделать его более строгим в отношении пробелов.* Добавлено A:

Если вы хотите сохранить все строки, кроме первой, в новом пути, тогда это будет делать:

var lines = File.ReadLines(path);
File.WriteLines(path2, lines.Skip(1));

Или если вы просто хотитемассив строк кроме первого, используйте это:

var linesExceptFirst = File.ReadLines(path).Skip(1);
0 голосов
/ 20 августа 2010

Я бы выбрал его в виде двух отдельных массивов.

using(StreamReader sr = new StreamReader(fileName)
{
  string header[] = sr.ReadLine().Split(' ');
  if(header.Length != 2) throw new InvalidDataException("yadda, yadda");

  List<string> lines = new List<string>(); 
  //you'll probably want to move that declaration outside the using statement...

  while(sr.Peek() != -1)
  {
    lines.Add(sr.ReadLine());
  }

  if(lines.Count() != int.Parse(header[1])) //this is wrong so...
    throw new InvalidDataException("yadda, yadda");

  if(lines.AsQueryable().Any(x => x.length != int.Parse(header[0]))// this, too
    throw new InvalidDataException("yadda, yadda");
}

Проблема в том, что в ваших образцах данных есть пробелы, и этот код не предполагает пробелов в данных.Поэтому нам нужно это исправить ...

List<string[]> separatedLines = new List<string[]>();

lines.ForEach(x => separatedLines.Add(x.Split(' ')));

if(separatedLines.AsQueryable().Any(s => s.Length != int.Parse(header[0])))
  throw new InvalidDataException("yadda, yadda");

Некоторые из них изменятся, если я неправильно понял ваши примеры данных, но сначала они возьмут строку заголовка и будут использовать ее значения для проверки остальныхваши данные.Перепроверьте меня по .AsQueryable() звонкам, хотя у меня не было такого большого количества шансов использовать Linq, как хотелось бы, поэтому я собираюсь получить относительно ограниченный опыт по этому вопросу.Я знаю, что когда я попробовал, использование методов Linq Extension в List заняло небольшую акробатику ...

Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...