Алгоритм форматирования текста в Паскаль или верблюжий корпус
Если использовать этот вопрос в качестве основы, то есть пример кодирования или кодирования для изменения текста на Pascal или Camel.
Например:
mynameisfred
становится
Camel: myNameIsFred
Pascal: MyNameIsFred
2 ответа
Я нашел ветку с кучей парней из Perl, которые обсуждают этот вопрос на http://www.perlmonks.org/?node_id=336331.
Я надеюсь, что это не слишком большая часть ответа на вопрос, но я бы сказал, что у вас есть небольшая проблема в том, что это будет очень открытый алгоритм, который также может иметь много "промахов" как хиты. Например, скажем, вы ввели:-
camelCase("hithisisatest");
Выход может быть:
"hiThisIsATest"
Или же:-
"hitHisIsATest"
Алгоритм не знает, какой из них выбрать. Вы можете добавить дополнительный код, чтобы указать, что вы предпочитаете более распространенные слова, но опять-таки произойдет промах (Питер Норвиг написал очень маленький корректор орфографии на http://norvig.com/spell-correct.html который может помочь алгоритму -потом, я написал реализацию C#, если C# - ваш язык).
Я согласен с Марком и скажу, что вам лучше иметь алгоритм, который принимает входные данные с разделителями, то есть this_is_a_test и преобразует их. Это было бы просто реализовать, то есть в псевдокоде:
SetPhraseCase(phrase, CamelOrPascal):
if no delimiters
if camelCase
return lowerFirstLetter(phrase)
else
return capitaliseFirstLetter(phrase)
words = splitOnDelimiter(phrase)
if camelCase
ret = lowerFirstLetter(first word)
else
ret = capitaliseFirstLetter(first word)
for i in 2 to len(words): ret += capitaliseFirstLetter(words[i])
return ret
capitaliseFirstLetter(word):
if len(word) <= 1 return upper(word)
return upper(word[0]) + word[1..len(word)]
lowerFirstLetter(word):
if len(word) <= 1 return lower(word)
return lower(word[0]) + word[1..len(word)]
Вы также можете заменить мою функцию capitaliseFirstLetter() подходящим алгоритмом регистра, если хотите.
AC# реализация описанного выше алгоритма выглядит следующим образом (полная консольная программа с тестовым жгутом):-
using System;
class Program {
static void Main(string[] args) {
var caseAlgorithm = new CaseAlgorithm('_');
while (true) {
string input = Console.ReadLine();
if (string.IsNullOrEmpty(input)) return;
Console.WriteLine("Input '{0}' in camel case: '{1}', pascal case: '{2}'",
input,
caseAlgorithm.SetPhraseCase(input, CaseAlgorithm.CaseMode.CamelCase),
caseAlgorithm.SetPhraseCase(input, CaseAlgorithm.CaseMode.PascalCase));
}
}
}
public class CaseAlgorithm {
public enum CaseMode { PascalCase, CamelCase }
private char delimiterChar;
public CaseAlgorithm(char inDelimiterChar) {
delimiterChar = inDelimiterChar;
}
public string SetPhraseCase(string phrase, CaseMode caseMode) {
// You might want to do some sanity checks here like making sure
// there's no invalid characters, etc.
if (string.IsNullOrEmpty(phrase)) return phrase;
// .Split() will simply return a string[] of size 1 if no delimiter present so
// no need to explicitly check this.
var words = phrase.Split(delimiterChar);
// Set first word accordingly.
string ret = setWordCase(words[0], caseMode);
// If there are other words, set them all to pascal case.
if (words.Length > 1) {
for (int i = 1; i < words.Length; ++i)
ret += setWordCase(words[i], CaseMode.PascalCase);
}
return ret;
}
private string setWordCase(string word, CaseMode caseMode) {
switch (caseMode) {
case CaseMode.CamelCase:
return lowerFirstLetter(word);
case CaseMode.PascalCase:
return capitaliseFirstLetter(word);
default:
throw new NotImplementedException(
string.Format("Case mode '{0}' is not recognised.", caseMode.ToString()));
}
}
private string lowerFirstLetter(string word) {
return char.ToLower(word[0]) + word.Substring(1);
}
private string capitaliseFirstLetter(string word) {
return char.ToUpper(word[0]) + word.Substring(1);
}
}
Единственный способ сделать это - пропустить каждую часть слова через словарь.
"mynameisfred" - это просто массив символов, разделение его на "Name Is Fred" означает понимание того, что означает объединение каждого из этих символов.
Вы могли бы сделать это легко, если бы ваш ввод был каким-то образом разделен, например, "мое имя - Фред" или "мое_имя_ис_фред".