PHP试题网_中国最大的免费网络PHP试题测试平台,PHP试卷调查,PHP试卷模板、PHP考试测验
公告: PHP试题网于2022.06.21变更为少儿编程学院
  • PHP面试题
  • 文章列表
  • 从字符串中查找出对称字符最长的字符串【江小白笔试题】[GO && PHP代码]

从字符串中查找出对称字符最长的字符串:规则:对称字符串,如oppo为对称, opo非对称。


思路:先找出相临一样的字符串,如pp,然后再左右扩散位置,再次对比是否一样,一样的话,再次扩散位置。以此类推,至到左右取出来的字符串不相同。


注:下面的算法只列出所有的对称字符串,可以根据length取最大值。

// 以下是GO代码,注意,有限制的。限制条件:相临位置相同字符为两位,最长6位对称(可由参数length=3控制单向移位)
package main

import (
    "fmt"
    "strings"
)

func main() {
    text := "example:geegopollopg"
    arr  := make([]string, 0)
    lentext := len(text)
    // 受限于go正则无法使用正则,只能先取两位挨个测试
    for k, _ := range text {
        if k + 1 > lentext - 1 {
            break
        }
        m := string(text[k])
        n := string(text[k+1])
        str := m + n
        if strings.Index(text, str) != -1   &&  m == n {
           arr = append(arr, str)
       }
    }
    //fmt.Printf("%+v",arr)
    //fmt.Println(len(arr))

    ret := make([]map[string]interface{}, 0)
    //循环arr
    length := 3 //移位最大长度为3
    for k, v := range arr {
        len2 := len(v)
        if len2 < 2 {
            break
        }
        idx := strings.Index(text, v)
        for i := 1; i <= length; i++ {
            im := idx - i
            in := idx + len2 + i - 1
            if im < 0 {
                break
            }
            sm := string(text[im])
            sn := string(text[in])
            fmt.Printf("第%d次大,第%d次小循环:idx位置:%d, 开始位置:%d, 结束位置:%d, 开始字符串:%v, 结束字符串:%v", k, i, idx, im, in, sm, sn)
            fmt.Println()
            if sm == sn {
                 ret = append(ret, map[string]interface{}{"idx":im, "length": in-im+1, "end":in, "begin":im})
            }
        }
    }
    fmt.Println()
    fmt.Println(ret)
    for k, v := range ret {
        //fmt.Println(k, v)
        ret[k]["ret"] = text[v["begin"].(int):v["end"].(int)+1]
        fmt.Printf("第%d次数据:%+v", k, v)
        fmt.Println()
    }

}

image.png



以下为PHP代码:

<?php
$test = 'example:geegopollopg';
$patter1 = "/(\w)\\1/";
preg_match_all($patter1, $test, $arr);
print_r($arr);

if(empty($arr[0])) {
   exit('empty $arr');
}

$ret = [];
echo $test."\n";
$length = 3;  //单向对称长度
foreach($arr[0] as $k => $v) {
    $left_length = strlen($v); //当前字符串长度
    $idx = stripos($test, $v); //当前第一次匹配到的对称字符串的位置
    echo '第',($k+1),'轮出现:', $v, ',位置:', $idx, "\n";
    for($i=1; $i <= $length; $i++) {
        $a = substr($test, $idx-$i, 1); //最左位置的字符串
        $b = substr($test, $idx + $left_length - 1 + $i, 1); //最右位置的字符串
        $m = $idx-$i; //得到最左位置
        $n = $idx + $left_length - 1 + $i; //得到最右位置
        echo '$idx='.$idx.', $idx-'.$i.'='.($idx-$i).'['.$a.'], $idx+'.$i.'='.($idx+$i).'['.$b.']'."\n";
        if($a == $b) {
            //$ret[$k] = substr($test, $idx - $left_length + $i , $left_length  + $i ); //这一步不能直接出结果,这里只能做记录
            $ret[] = ['a_idx'=>$idx-$i, 'a'=>$a, 'length'=>$n-$m+1, 'ret'=>substr($test, $m, $n-$m+1)];//记录最左位置、最左字符串、字符串最长长度
        }
        echo "\n";
    }
}
print_r($ret);

image.png


作者:OK兄 浏览次数:38