Поиск одинаково разделенной строки / слов в алфавитном порядке в Go - PullRequest
0 голосов
/ 19 октября 2019

Я пытаюсь найти слова / строки, которые одинаково разделены внутри кругового расположения алфавита. например:

  • «zzzzyyyybbbzzzaaaaaxxx» - это список, состоящий из «xyzab» с разделением 0 {xy, yz, za, ab}
  • «aco» - это список с разделением 11{co, oa}

Следовательно, я хотел написать функцию IsSeparated (B) и возвращать true, если B "isSeparated"

Ниже приведены мои коды / решение:

  • во-первых, я попытался удалить дубликаты в строке, чтобы было легче подсчитать разделение
  • , во-вторых, я отсортировал строку в алфавитном порядке
  • , третье, послесортируя, я подсчитываю разделение для каждой буквы
  • в методе "isSeparated". Я попытался подсчитать его по кругу, используя maxpair -1 == count, так как всегда будет 1 буква, в которой нет пары, например
  • [{ab} {bx} {xy} {yz} {za}] - [{0} {21} {0} {0} {0}]]//there are 5 pairs = maxPair -1({-xy}

следовательно, поскольку он находится в круговом расположении, средний всегда будет нечетным, то есть 21, которые не разделены поровну с остальнымипары

Это та часть, где этостановится сложно, и я не могу получить желаемый результат. что может быть правильным способом найти длину / разделение каждой буквы в алфавитном порядке и проверить, равномерно ли они разделены.


package main

import (
    "fmt"
    "strings"
)

//Q3
func separationCount(x, y string) int {
    alphabets := [26]string{"a","b","c","d", "e", "f", "g", "h", "i", "j", "k", "l", "m", "n", "o", "p", "q", "r", "s", "t", "u","v", "w", "x", "y", "z"}
    separation := 0

    for i:=0; i < len(alphabets); i++{
        if x == alphabets[i]{

            for j:= i+1; j <len(alphabets); j++{
            if y == alphabets[i+1]{
            fmt.Println(separation)
            return separation
            }else{
                i++
                separation++
            } 
            }
                }else{
            //do nothing
        }
    }
    //fmt.Println(separation)
    return 0
}

func isSeparated(B [] string) bool {
    var N int = len(B) - 1
    var maxPair int
    var item1 string
    var item2 string
    var separation int = 0 
    count := 0
    var intialSeparation int

    //calling the methods
    fmt.Println("Original array:",B)
    B = removeDuplicates(B)
    B = sortedList(B)

    item1 = B[0]
    item2 = B[1]
    intialSeparation = separationCount(item1,item2)

    for i := 0; i< N; i++{
        item1 = B[i]
        item2 = B[i + 1]

        separation = separationCount(item1,item2)
        maxPair++
        if intialSeparation == separation{
            count++
        }

        if maxPair == count{
            return true
        }else{
            return false
        }

    }
    return false
}

//to sort the alphabets 
func sortedList(B []string) [] string {
    N  := len(B)
    //max := 0
    element1 := 0 
    element2 := 1

    for element2 < N {
        var item1 string = B[element1]
        var item2 string = B[element2]

        //using function call
        if greater(item1, item2){
            B[element1] = item2
            B[element2] = item1
        }
        element1++
        element2++
    } 
    fmt.Println("Alphabetically sorted:", B )
    return B
}

//for sorting
func greater(a, b string) bool {
    if strings.ToLower(a) > strings.ToLower(b) {
      return true
    } else {
      return false
    }
  }

  //removing duplicates
func removeDuplicates(B []string) []string {
    encountered := map[string]bool{}

    // Create a map of all unique elements.
    for v:= range B {
        encountered[B[v]] = true
    }

    // Place all keys from the map into a slice.
    result := []string{}
    for key, _ := range encountered {
        result = append(result, key)
    }
    fmt.Println("Duplicates removed:", result )
    return result
}

func main(){
    //q3
    B := []string{"y", "a", "a", "a", "c", "e", "g", "w", "w", "w"}
    fmt.Println(isSeparated(B))
}



1 Ответ

1 голос
/ 19 октября 2019

Я не совсем понимаю ту часть, где вы пытаетесь определить разделение. В Go, как и в C, вы можете делать арифметику для персонажей. Например, вы получите индекс на основе 0 каждой буквы в нижнем регистре с:

pos := char - 'a';

. Вы можете повернуть "abxyz" в

{0, 1, 23, 24, 25}.

. разницу между соседними буквами вы получите

{-25, 1, 22, 1, 1}

(- разница между последним и первым значением - 25). У вас есть два пробела: один, где начинается ваш цикл между b и w, и другойгде алфавит окутывает. Второй разрыв - это где разница отрицательна, всегда между последним и первым пунктами. Вы можете добавить 26 к разнице, чтобы скорректировать ее, или использовать модульную арифметику, где вы используете остаток % для учета переноса:

diff := ((p - q + 26) % 26;

% приводит результат к диапазонуот 0 до 25, если первый операнд положительный. + 26 обеспечивает, что это положительно. (В приведенной ниже программе используется 25, потому что ваше определение разделения - это не разница в положении, а количество промежуточных букв.)

Теперь у вас есть различия

{1, 1, 22, 1, 1}

Когда выне более двух различных значений, и одно из них встречается не более одного раза, ваше условие выполнено. (Это условие, которое я нахожу удивительно сложным для тестирования, см. Ниже, но отчасти это связано с тем, что карта Го немного громоздка.)

В любом случае, вот код:

package main

import "fmt"

func list(str string) int {
    present := [26]bool{}
    pos := []int{}

    count := map[int]int{}

    // determine which letters exist
    for _, c := range str {
        if 'a' <= c && c <= 'z' {
            present[c-'a'] = true
        }
    }

    // concatenate all used letters (count sort, kinda)
    for i := 0; i < 26; i++ {
        if present[i] {
            pos = append(pos, i)
        }
    }

    // find differences
    q := pos[len(pos)-1]
    for _, p := range pos {
        diff := (p - q + 25) % 26

        count[diff]++
        q = p
    }

    // check whether input is a "rambai"
    if len(count) > 2 {
        return -1
    }

    which := []int{}
    occur := []int{}
    for k, v := range count {
        which = append(which, k)
        occur = append(occur, v)
    }

    if len(which) < 2 {
        return which[0]
    }

    if occur[0] != 1 && occur[1] != 1 {
        return -1
    }

    if occur[0] == 1 {
        return which[1]
    }

    return which[0]
}

func testme(str string) {
    fmt.Printf("\"%s\": %d\n", str, list(str))
}

func main() {
    testme("zzzzyyyybbbzzzaaaaaxxx")
    testme("yacegw")
    testme("keebeebheeh")
    testme("aco")
    testme("naan")
    testme("mississippi")
    testme("rosemary")
}

https://play.golang.org/p/ERhLxC_zfjl

...