php Substitution Encoding Algorithm using cesar ci

2019-07-25 12:54发布

问题:

hello i am stack with this exercise as part of a test, how can i solve it or hint to solve it

/**
 * Class SubstitutionEncodingAlgorithm
 */
class SubstitutionEncodingAlgorithm implements EncodingAlgorithm {

    /**
     * @var array
     */
    private $substitutions;

    /**
     * SubstitutionEncodingAlgorithm constructor.
     * @param $substitutions
     */
    public function __construct(array $substitutions) {
        $this->substitutions = array();
    }

    /**
     * Encodes text by substituting character with another one provided in the pair.
     * For example pair "ab" defines all "a" chars will be replaced with "b" and all "b" chars will be replaced with "a"
     * Examples:
     *      substitutions = ["ab"], input = "aabbcc", output = "bbaacc"
     *      substitutions = ["ab", "cd"], input = "adam", output = "bcbm"
     *
     * @param string $text
     * @return string
     */
    public function encode($text) {
        /**
         * @todo: Implement it
         */
    }

}

that what i ve tried so far in the encode () function but its not working, what i am doing wrong ?

public function encode($text) {
    $length = strlen($text);
            $newstr = '';
            for ($i = 0; $i < $length; $i++) {
                if (is_array($this->substitutions) && in_array(strtoupper($text[$i]), array_flip($this->substitutions)))
                    $newstr .= $this->substitutions[strtoupper($text[$i])];
            }


            return $newstr;
        }

i understand that it is the cesar algorithm to be implemented so far, any help would be appreciated on how to do it

回答1:

You could take the substitutions array and split it into two arrays, e.g.

$swapA = array();
$swapB = array();

//for each item in the substitutions array take the first char
// and place in swapA and the second/last char and place in swapB
foreach($substitutions as $sub)
{
    $swapA = substr($sub,0,1);
    $swapB = substr($sub,1,1);
}
// the str_replace will replace the all characters in $text chars 
// from position x in swapA with chars in the same position in swapB 

$output = str_replace($swapA, $swapB, $text);


回答2:

        $swapA = array();
        $swapB = array();
        $output = '';
        $aText = str_split($text);
        foreach($this->substitutions as $sub)
        {
            $swapA[] = substr($sub,0,1);
            $swapB[] = substr($sub,1,1);

        }

        foreach ($aText as $letter) {
            if (in_array(strtolower($letter, $swapA)) {
                $positionOccurence = array_search ($letter, $swapA);
                $replaced = $swapB[$positionOccurence];
                $output .= str_replace($letter, $replaced, $letter);
            } elseif (in_array(strtolower($letter), $swapB)) {
                $positionOccurence = array_search ($letter, $swapB);
                $replaced = $swapA[$positionOccurence];
                $output .= str_replace($letter, $replaced, $letter);
            } else {
                $output .= $letter;
            }
        }

        return $output;


回答3:

My try - it is just for one byte per char text:

private function encodeText (string $text) : string {

    $result = '';

    for ($i = 0, $e = strlen ($text); $i < $e; $i ++) {
        foreach ($this->substitutions as $substitution) {
            $strpos = strpos ($substitution, $text {$i});
            if ($strpos !== false) {
                $result .= $strpos == 0 ? $substitution {1} : $substitution {0};
                continue 2;
            }
        }

        $result .= $text {$i};
    }

    return $result;
}

Other solution is much more faster and simpler:

first create in constructor array like:

    foreach ($substitutions as $substitution) {
        $this->substitutions ['from'] .= $substitution {0} . $substitution {1} . strtoupper($substitution {0} . $substitution {1});
        $this->substitutions ['to'] .= $substitution {1} . $substitution {0} . strtoupper($substitution {1} . $substitution {0});
    }

and then simply make translation:

public function encode($text)
{
    return strtr ($text, $this->substitutions ['from'],  $this->substitutions ['to']);
}