[C#] Домашно Strings and Text Processing - 5 задача


17

Условие: You are given a text. Write a program that changes the text in all regions surrounded by the tags <upcase> and </upcase> to uppercase. The tags cannot be nested. Example:

We are living in a <upcase>yellow submarine</upcase>. We don't have <upcase>anything</upcase> else.

The expected result:

We are living in a YELLOW SUBMARINE. We don't have ANYTHING else.

Решениеsource.

Обяснение: Използваме "нелаком" (да не вземе първия отварящ и последния затварящ) регулярен израз за да изберем таговете, след което с ToUpper() правим тяхното съдържание с главни букви.




Отговори



6

Решението:

http://pastebin.com/kbM9GWc3

Обяснение:

1. Създавам си две променливи startIndex и endIndex, като това е диапазона в който е текста който трябва да направя с главни букви, един вид м/у таговете.

2. Пускам for цикъл до str.Length - 8, (минус осем, защото да не излезе от stringa)

3. След това започвам да търся substring(парче от стринга) който отговаря на <upcase>.

4. Щом намеря такова го записвам в startIndex индекса на който го е намерил и добавям дължината на <upcase> за да запиша индекса точно след него. От където ще започна да правя текста с главни букви. Също така за да не обхождам и проверявам следващите 8 индекса, дали отговарят на търсения substring, прескачам там където ми е startIndex-a, като присвоявам на i=startIndex (лека оптимизация)

5. Аналогично като т.3 с разликата че тук тага вече е с дължина 9 символа.

6. Присвоявам на endIndex-a, индекса на който съм го октрил тага </upcase>.

7. След това създвам нова променлива upperStr на която и присвоявам - текста в диапазона който искам да е с главни букви, като го правя с главни без значение какви са.

8. Махам в str текста в диапазона от startIndex до endIndex.

9. Insert в str на позиция startIndex upperStr. Вече буквите са главни остава само да махна таговете..

10. Махам първия таг, след това втория таг като използвам startIndex endIndex , за тяхното местоположение.

Накрая Принтвам новия СТРИНГ :)

 

Асси


от Assi.NET (3050 точки)


0
Може цикъла да го въртиш не до str.Lenght - 8, ами направо -17.

от AlexPopov (1568 точки)

0
Трябва да го въртиш до str.Lenght - (дължината на последният таг). Така както казваш ти не става, защото последния таг ако е точно накрая или малко по напред в масива ти няма да го обходиш и достигнеш от там ти е ясно какъв ще е резултата :)

от Assi.NET (3050 точки)



0
Реших задачата без регулярни изрази, но нещо ме запъва решението й с такива. Тъй като още не съм прегледал доста неща (най-вече тези свързани с LINQ), искам да направя по-различно решение. Стигнах до следния регулярен израз:
line = Regex.Replace(line, "()", "$2".ToUpper());
Във всичките му варианти, включително и този:
line = Regex.Replace(line, "()", s=Convert.ToString("$2").ToUpper());
ми връща съдържанието на таговете, без да го е конвентирало до стринг с главни букви.
Някой има ли идея защо се получава така? Подозирам, че и в двата случая методът ToUpper се вика върху стринга "$2", а не върху това, което трябва да се върне от него, но нямам никаква идея как да заобиколя проблема.

от petarpenev (3148 точки)


0
Разгледай тази тема: http://stackoverflow.com/questions/205382/regular-expression-uppercase-replacement-in-c-sharp Трябва с ламбда израз или да вземеш групите.

от jasssonpet (6814 точки)

0
Ще трябва да се научат тия регулярни изрази, само да намеря малко време :)

от Assi.NET (3050 точки)



0

1. Търся индексите на стринговете <upcase> и </upcase> по зададени начални индекси. За първия начален индекс е 0, за втория началният индекс е индекса на <upcase> + броя ня символите в него - 8.

2. Търсенето става в while цикъл, в който е зададено условие той да работи когато началният индекс на търсене е > -1. Не е == -1 както в предните задачи, защото съм създал глобална променлива за начален индекс = 0, а и той трудно би станал -1, тъй като в края на всеки цикъл се увеличава с 9 заради дължината на затварящия таг.

3. При намиране на търсените индекси продължаваме нататък, ако ли не while цикъла приключва.

4. На база търсените стрингове и техните индекси, намираме съдържанието между тях.

5. Чрез Replace го заменяме с неговата равностойност в UpperCase. 

6. While цикъла може да спре винаги когато не бъден намерен отварящ или затварящ таг.

решение




0
В условието трябва да махнеш и 2-та тага... Най-грубият начин е да завъртиш отново същият while и да ги извадиш с 2 субстринга и да ги replace-неш със string.empty.


0
Благодаря ти! Добавих само два реда със метода string.replace(string, string).




13

Решение: http://pastebin.com/Jpm6Y31t

Обяснение:

Направил съм го с метод и може да се зададе какъвто си искаш таг.

Алгоритъма е като намериш на коя посиция са <upcase> и </upcase> между тях просте го text.Replace() с новия текс .ToUpper();

Въртиш цикъла докато има тагове!

Без регулярни изрази е!


от deyan.keray (266 точки)


0
Много хубаво решение. На база материала до момента. Особено готино си се сетил да направиш възможно ползване на всякакъв вид таг! БРАВО! Само махни тоя брояч горе дето се мъдри, че нещо не се използва :)

от stoyankm (5 точки)

0
Не разбрах как ще работи за всички тагове като накрая си написал text = text.Replace(TagStart + temp + TagEnd, temp.ToUpper()); тоест винаги е .ToUpper ?

от IceElementor (398 точки)


0

Рениение без Regex.




1

Тия regular expressions на фона на моето решение с няколко метода направо ме карат да седна да ги науча. Само да напиша тия домашни и са на ред те!

Ето го и решението с методи и листове за индексите:

http://pastebin.com/ZjeKftSK


от sylviapsh (302 точки)


0
Да, наистина са много полезни. Ако се ползват и ламбда изрази се получават кратки и ясни решения.

от jasssonpet (6814 точки)

0
Да ама Дончо каза, че на изпита освен ако не ги знаем много добре, няма да ни помогнат изключително много.




1
Решение без Regex от мен: http://pastebin.com/h0YwJsW7
1.Проверяваме броя на таговете в текста.
2.Завъртаме цикъл, с който проверяваме къде е краят на отварящият таг, после къде е началото на затварящият и вземаме тексата между двата със Substring. После изчистваме съдържанието с Remove и добавяме Insert-ваме същият текст, но със главни букви. Накрая излизаме извън затварящият таг и завъртаме цикъла отново.

от petromaxa (577 точки)


1

Браво на jasssonpet, с това решение те признах.
Ето и моето решение , доста прочетох преди да го напиша, в крайна сметка прави, същото което прави ламбда израза на jasssonpet, но си мисля, че така разписано е с една идея по-ясно и разбираемо за хората, които все още сме начинаещи.
Създавам си един обект
Regex regex = new Regex (@"(<\s*upcase\s*>)(?<tag>.*?)(<\s*/upcase\s*>)");
и една колекция в която да пазя съвпаденията
MatchCollection matches = regex.Matches(str);
С един foreach цикъл обхождам съвпаденията и за всяко съвпадение по един път замествам с Replace, замествам съвпадението със стойността на групата "tag" и приложен метод за главни букви
str = regex.Replace(str, match.Groups["tag"].Value.ToUpper(),1);


от AsenVal (3487 точки)


0
Може ли да обясниш само единичката в края на Replace метода за какво служи?

от rnikiforova (1198 точки)

0
аз горе го написах, но можеби не съм бил достатъчно ясен. Единицата е за да може на всяко съвпадение само по един път да си изпълнява Replace метода, защото без нея още при първото съвпадение всички съвпадения ще бъдат заместени със стойността на Groups[...] от първото съвпадение, а не от сътветното съвпадение. Незнам дали го обясних ясно, пробвай го с и без 1 и ще го разбереш.

от AsenVal (3487 точки)


2
Ето решение без с което заместваме 2-та тага + текста между тях с текста само че с главни букви.
http://pastebin.com/Vw2bVuAL

от makmidov (598 точки)


0

Решение

затрудни ме тази задача, въпреки че отначало мислех че набързо ще я реша. Та стринга го правя на масив, за да може да променям символите в него, след като ги направя на главни букви си го обръщам пак в стринг и премахвам вече таговете с Replace.


от Rokata (397 точки)