2

エンターテイナーとそのパフォーマンス スコアに関するデータを含む入力ファイルがあります。例えば、

1. Bill Monohan from North Town 10.54
2. Mary Greenberg from Ohio 3.87
3. Sean Hollen from Markell 7.22

行 (スコア) から最後の数字を取得し、それに対していくつかの計算を実行してから、古いスコアを新しいスコアに置き換えたいと考えています。私がやろうとしていることの簡単なコードは次のとおりです。

string line;
StreamReader reader = new StreamReader(@"file.txt");

//Read each line and split by spaces into a List.
while ((line = reader.ReadLine())!= null){

//Find last item in List and convert to a Double in order to perform calculations.
   List<string> l = new List<string>();
   l = line.Split(null).ToList();
   string lastItem = line.Split(null).Last();
   Double newItem = Convert.ToDouble(lastItem);

   /*Do some math*/
   /*Replace lastItem with newItem*/
   System.Console.WriteLine(line); }

新しい行を書いても何も変わりませんが、行末で lastItem を newItem に切り替えたいと思います。私は使用してみました:

l[l.Length - 1] = newItem.ToString();

しかし、私は運がありません。このような文字列リストの最後の値を置き換える最良の方法が必要です。私はこれを数時間行ってきましたが、ロープの終わりに近づいています。C#マスターを助けてください!

4

6 に答える 6

2

正規表現MatchEvaluatorを使用して、各行から数値を取得し、計算を行い、元の数値を新しい数値に置き換えることができます。

string line = "1. Bill Monohan from North Town 10.54";
line = Regex.Replace(line, @"(\d+\.?\d*)$", m => {
            decimal value = Decimal.Parse(m.Groups[1].Value);
            value = value * 2; // calculation
            return value.ToString();
        });

この正規表現は、入力文字列の末尾にある 10 進数をキャプチャします。出力:

1. Bill Monohan from North Town 21.08
于 2013-09-23T09:06:23.387 に答える
0

これはおそらくあなたのために仕事をするでしょう. ただし、可能であれば、ファイルの読み取りについて一言、つまり、ファイルがメモリに収まり、ファイル全体を一度に読み取ると、1 つのディスク アクセスが可能になり (ファイル サイズにもよりますが、そうです)、ファイルハンドルについて心配する必要はありません。

  // Read the stuff from the file, gets an string[]
  var lines = File.ReadAllLines(@"file.txt");

  foreach (var line in lines)
  {
      var splitLine = line.Split(' ');
      var score = double.Parse(splitLine.Last(), CultureInfo.InvariantCulture);

      // The math wizard is in town!
      score = score + 3;

      // Put it back
      splitLine[splitLine.Count() - 1] = score.ToString();

      // newLine is the new line, what should we do with it?
      var newLine = string.Join(" ", splitLine);
      // Lets print it cause we are out of ideas!
      Console.WriteLine(newLine);
  }

最終結果で何をしたいですか?ファイルに書き戻しますか?

于 2013-09-23T09:07:38.920 に答える
0

これを試して

  string subjectString = "Sean Hollen from Markell 7.22";

  double Substring =double.Parse(subjectString.Substring(subjectString.IndexOf(Regex.Match(subjectString, @"\d+").Value), subjectString.Length - subjectString.IndexOf(Regex.Match(subjectString, @"\d+").Value)).ToString());

  double NewVal = Substring * 10;  // Or any of your operation

  subjectString = subjectString.Replace(Substring.ToString(), NewVal.ToString());

注:番号が同じ行に 2 回表示される場合、これは機能しません。

于 2013-09-23T09:08:18.580 に答える
0

ループでリストを作成および初期化しているため、常に現在の行のみが含まれます。すべてのエンターテイナーの最高スコアを検索しますか、それとも各エンターテイナーの最高スコアを検索しますか (エンターテイナーがファイルで繰り返す可能性がある場合)?

ただし、両方を提供するアプローチを次に示します。

var allWithScore = File.ReadAllLines(path)
    .Select(l =>
    {
        var split = l.Split();
        string entertainer = string.Join(" ", split.Skip(1).Take(split.Length - 2));
        double score;
        bool hasScore = double.TryParse(split.Last(), NumberStyles.Float, CultureInfo.InvariantCulture, out score);
        return new { line = l, split, entertainer, hasScore, score };
    })
    .Where(x => x.hasScore);
// highest score of all:
double highestScore = allWithScore.Max(x => x.score);
// entertainer with highest score 
var entertainerWithHighestScore = allWithScore
    .OrderByDescending(x => x.score)
    .GroupBy(x => x.entertainer)
    .First();
foreach (var x in entertainerWithHighestScore)
    Console.WriteLine("Entertainer:{0} Score:{1}", x.entertainer, x.score);
// all entertainer's highest scores:
var allEntertainersHighestScore = allWithScore
    .GroupBy(x => x.entertainer)
    .Select(g => g.OrderByDescending(x => x.score).First());
foreach (var x in allEntertainersHighestScore)
    Console.WriteLine("Entertainer:{0} Score:{1}", x.entertainer, x.score);
于 2013-09-23T09:11:14.963 に答える
0

WriteLine を実行する前に、line オブジェクトに何も変更していません。

次のように、ラインを再構築する必要があります。

var items = string.Split();
items.Last() = "10";//Replace
var line = string.Join(" ", items)

ヒント: 文字列は不変です。調べてください。

于 2013-09-23T08:54:08.473 に答える