ReverseString, вопрос C # интервью - PullRequest
10 голосов
/ 18 июня 2009

У меня был вопрос на собеседование, который попросил меня написать «отзыв» о куске кода, который написал младший программист. Они намекнули, что может быть проблема, и сказали, что они будут интенсивно использоваться на больших струнах.

public string ReverseString(string sz)
{
    string result = string.Empty;
    for(int i = sz.Length-1; i>=0; i--)
    {
      result += sz[i]
    }
    return result;
}

Я не мог определить это. Я не видел никаких проблем вообще. Оглядываясь назад, я мог бы сказать, что пользователь должен изменить размер, но похоже, что C # не имеет изменения размера (я парень C ++).

Я закончил тем, что написал такие вещи, как использование итератора, если это возможно, [x] в контейнерах не может быть произвольного доступа, поэтому он может быть медленным. и разные вещи. Но я определенно сказал, что мне никогда не приходилось оптимизировать код на C #, поэтому моё мышление не подвело меня на собеседовании.

Я хотел знать, в чем проблема с этим кодом, вы, ребята, видите его?

-edit-

Я изменил это в вики, потому что может быть несколько правильных ответов. Также я очень рад, что прямо сказал, что мне никогда не приходилось оптимизировать программу на C #, и упомянул разные вещи. К сожалению. Я всегда думал, что у C # не было проблем с производительностью такого рода вещей. упс.

Ответы [ 12 ]

0 голосов
/ 18 сентября 2017
 static string reverseString(string text)
    {
        Char[] a = text.ToCharArray();
        string b = "";
        for (int q = a.Count() - 1; q >= 0; q--)
        {
            b = b + a[q].ToString();
        }
        return b;
    }
0 голосов
/ 30 марта 2016

Некромантия.
Как общедоступная служба, именно так вы на самом деле ПРАВИЛЬНО переворачиваете строку
(обращение строки НЕ равно обращению последовательности символов )

public static class Test
{

    private static System.Collections.Generic.List<string> GraphemeClusters(string s)
    {
        System.Collections.Generic.List<string> ls = new System.Collections.Generic.List<string>();

        System.Globalization.TextElementEnumerator enumerator = System.Globalization.StringInfo.GetTextElementEnumerator(s);
        while (enumerator.MoveNext())
        {
            ls.Add((string)enumerator.Current);
        }

        return ls;
    }


    // this 
    private static string ReverseGraphemeClusters(string s)
    {
        if(string.IsNullOrEmpty(s) || s.Length == 1)
             return s;

        System.Collections.Generic.List<string> ls = GraphemeClusters(s);
        ls.Reverse();

        return string.Join("", ls.ToArray());
    }

    public static void TestMe()
    {
        string s = "Les Mise\u0301rables";
        // s = "noël";
        string r = ReverseGraphemeClusters(s);

        // This would be wrong:
        // char[] a = s.ToCharArray();
        // System.Array.Reverse(a);
        // string r = new string(a);

        System.Console.WriteLine(r);
    }
}

См: https://vimeo.com/7403673

Кстати, на Голанге правильный путь таков:

package main

import (
  "unicode"
  "regexp"
)

func main() {
    str := "\u0308" + "a\u0308" + "o\u0308" + "u\u0308"
    println("u\u0308" + "o\u0308" + "a\u0308" + "\u0308" == ReverseGrapheme(str))
    println("u\u0308" + "o\u0308" + "a\u0308" + "\u0308" == ReverseGrapheme2(str))
}

func ReverseGrapheme(str string) string {

  buf := []rune("")
  checked := false
  index := 0
  ret := "" 

    for _, c := range str {

        if !unicode.Is(unicode.M, c) {

            if len(buf) > 0 {
                ret = string(buf) + ret
            }

            buf = buf[:0]
            buf = append(buf, c)

            if checked == false {
                checked = true
            }

        } else if checked == false {
            ret = string(append([]rune(""), c)) + ret
        } else {
            buf = append(buf, c)
        }

        index += 1
    }

    return string(buf) + ret
}

func ReverseGrapheme2(str string) string {
    re := regexp.MustCompile("\\PM\\pM*|.")
    slice := re.FindAllString(str, -1)
    length := len(slice)
    ret := ""

    for i := 0; i < length; i += 1 {
        ret += slice[length-1-i]
    }

    return ret
}

И неправильный способ таков (ToCharArray.Reverse):

func Reverse(s string) string {
    runes := []rune(s)
    for i, j := 0, len(runes)-1; i < j; i, j = i+1, j-1 {
        runes[i], runes[j] = runes[j], runes[i]
    }
    return string(runes)
}

Обратите внимание, что вам нужно знать разницу между
- персонаж и глиф
- байт (8 бит) и кодовая точка / руна (32 бита)
- кодовая точка и GraphemeCluster [32+ бит] (он же Grapheme / Glyph)

Справка:

Символ - перегруженный термин, который может означать много вещей.

Кодовая точка - это атомная единица информации. Текст представляет собой последовательность кодовые точки. Каждая кодовая точка - это число, которому Стандарт Юникод.

Графема - это последовательность одной или нескольких отображаемых кодовых точек. как единая графическая единица, которую читатель распознает как единый элемент системы письма. Например, и a, и ä являются графемы, но они могут состоять из нескольких кодовых точек (например, две кодовые точки, одна для базового символа, а затем одна для диарез; но есть и альтернатива, устаревшая, единая кодовая точка представляя эту графему). Некоторые кодовые точки никогда не являются частью какого-либо графема (например, несоединение нулевой ширины или переопределение направления).

Глиф - это изображение, обычно хранящееся в шрифте (который является коллекцией глифов), используется для обозначения графем или их частей. Шрифты могут составить несколько глифов в одном представлении, например, если Вышеприведенный ä представляет собой одну кодовую точку, шрифт может выбрать для два отдельных, пространственно наложенных глифа. Для OTF, шрифта GSUB и Таблицы GPOS содержат информацию о замене и позиционировании эта работа. Шрифт может содержать несколько альтернативных глифов для одного и того же графема тоже.

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