シンプルな並べ替えアルゴリズム - フロントエンドの視覚的表示

序文

この波が現実になるとは予想していませんでした。午後は満腹で、友達と自慢したり、chatgpt をプレイしたり、その後、chatgpt でそのような効果を達成するプログラムを作成できるかどうかを考えました。ソート アルゴリズムを表示します。実行結果は次のとおりです。入力データをカスタマイズし、各実行の結果を表示します。

次に、chatgpt にそれを生成させ、継続的なデバッグと chatgpt との通信を通じて、最終的に目に見えるドームを取得します。

ここに画像の説明を挿入

将来的には、これに基づいてユーザーがコードを入力できるようにする予定です。そのような効果を実現するには:
ここに画像の説明を挿入
しかし、問題は、返されるコードには常にバグがあり、レイアウトに特定の問題があり、最終的には、コードはデバッグのために手動で変更することしかできないということです。言い換えれば、彼はコードの少なくとも 90% を生成し、私はアセンブル、変更、デバッグのみを担当しました。確かに効率は向上しており、特に単純なロジックの実現はコードジェネレータでは不可能ですが、それでも人間に比べて比較的面倒な作業です。

データフレーム

次に、このコードの中心となるプロセスについて簡単に説明します。実際、このコードは非常に単純です。

new Vue({
    
    
            el: '#app',
            data: {
    
    
                input: '5, 4, 3, 2, 1',
                history: [],
                currentFrame: -1,
                maxFrame: -1,
                intervalId: null,
            },
            methods: {
    
    
                sort() {
    
    
                    this.history = [];
                    let list = this.input.split(',').map(Number);
                    let maxHeight = 10;
                    this.render(list.slice(), maxHeight);
                    for (let i = 0; i < list.length - 1; i++) {
    
    
                        for (let j = 0; j < list.length - i - 1; j++) {
    
    
                            if (list[j] > list[j + 1]) {
    
    
                                let temp = list[j];
                                list[j] = list[j + 1];
                                list[j + 1] = temp;
                                this.history.push(list.slice());
                            }
                        }
                    }
                    this.history.push(list.slice());
                    this.maxFrame = this.history.length - 1;
                    this.currentFrame = 0;
                    this.render(this.history[this.currentFrame], maxHeight);
                    this.updateLabel();
                },
                render(list, maxHeight) {
    
    
                    let outputDiv = document.getElementById('output');
                    outputDiv.innerHTML = '';
                    let scaleFactor = maxHeight / Math.max(...list);
                    for (let i = 0; i < list.length; i++) {
    
    
                        let bar = document.createElement('div');
                        bar.className = 'bar';
                        bar.style.height = `${
      
      scaleFactor * 20 * list[i]}px`;
                        bar.innerText = list[i].toString();
                        outputDiv.appendChild(bar);
                    }
                },
                nextStep() {
    
    
                    if (this.currentFrame < this.maxFrame) {
    
    
                        this.currentFrame++;
                        this.render(this.history[this.currentFrame], 10);
                        this.updateLabel();
                    }
                },
                prevStep() {
    
    
                    if (this.currentFrame > 0) {
    
     // 当前帧数大于0时才执行操作
                        this.currentFrame--;
                        this.render(this.history[this.currentFrame], 10);
                        this.updateLabel();
                    }
                },
                restart() {
    
    
                    this.currentFrame = -1;
                    this.sort();
                },
                updateLabel() {
    
    
                    let label = `Step ${
      
      this.currentFrame + 1} of ${
      
      this.maxFrame + 1}`;
                    document.getElementById('step-label').innerText = label;
                },
                play() {
    
    
                    if (this.intervalId) {
    
    
                        clearInterval(this.intervalId);
                        this.intervalId = null;
                    } else {
    
    
                        this.intervalId = setInterval(() => {
    
    
                            if (this.currentFrame < this.maxFrame) {
    
    
                                this.nextStep();
                            } else {
    
    
                                clearInterval(this.intervalId);
                                this.intervalId = null;
                            }
                        }, 500);
                    }
                },
            },
            mounted() {
    
    
                this.sort();
            },
        });

ここでバブル ソートを実装していることがわかります。交換やデータ変更があるたびに、現在の配列をコピーして履歴配列に置きます。その後、呼び出し時に表示されます。元のデータを取得し、データを表すヒストグラムを作成します。

それがこのコードです:

          render(list, maxHeight) {
    
    
                    let outputDiv = document.getElementById('output');
                    outputDiv.innerHTML = '';
                    let scaleFactor = maxHeight / Math.max(...list);
                    for (let i = 0; i < list.length; i++) {
    
    
                        let bar = document.createElement('div');
                        bar.className = 'bar';
                        bar.style.height = `${
      
      scaleFactor * 20 * list[i]}px`;
                        bar.innerText = list[i].toString();
                        outputDiv.appendChild(bar);
                    }
                },

並べ替えの視覚化

その後に、視覚的に表示するための完全なコードが続きます。

<!DOCTYPE html>
<html>

<head>
    <meta charset="UTF-8">
    <title>Bubble Sort Visualization</title>
    <link rel="stylesheet" href="https://cdn.bootcss.com/bootstrap/4.3.1/css/bootstrap.min.css">
    <style>
        .bar {
      
      
            background-color: blue;
            margin: 2px;
            display: inline-block;
            vertical-align: bottom;
            width: 40px;
            text-align: center;
            color: white;
            font-weight: bold;
        }
        
        #output {
      
      
            margin-bottom: 20px;
        }
        
        #step-label {
      
      
            font-size: 24px;
            font-weight: bold;
            margin-top: 10px;
            width: 100%;
        }
        
        #app>form>.form-row {
      
      
            display: flex;
            align-items: center;
            justify-content: space-between;
        }
        
        #app>form>.form-row>.col-sm-8 {
      
      
            display: flex;
            align-items: center;
            padding-right: 5px;
        }
        
        #app>form>.form-row>.col-sm-4 {
      
      
            display: flex;
            align-items: center;
            justify-content: flex-end;
            flex-wrap: nowrap;
            padding-left: 5px;
            width: 180px;
        }
        
        #sort-button {
      
      
            width: 70px !important;
            text-overflow: ellipsis;
            white-space: nowrap;
            overflow: hidden;
            margin-left: 5px;
        }
        
        #app>.row>.col-sm:not(:first-child) {
      
      
            margin-top: 10px;
        }
        
        #play-button {
      
      
            background-color: #007bff;
            color: white;
            border: none;
            font-weight: bold;
            width: 40px;
            height: 40px;
            border-radius: 50%;
            position: relative;
            transition: all .2s ease-in-out;
        }
        
        #play-button:hover {
      
      
            opacity: 0.8;
        }
        
        #play-button:active:after {
      
      
            content: "";
            display: block;
            position: absolute;
            top: 50%;
            left: 50%;
            transform: translate(-50%, -50%);
            width: 0;
            height: 0;
            border-style: solid;
            border-width: 10px 0 10px 20px;
            border-color: transparent transparent transparent #fff;
        }
        
        .btn-group>.btn {
      
      
            margin-left: 5px;
            margin-right: 5px;
        }
    </style>
</head>

<body>
    <div id="app" class="container mt-5">
        <h1 class="mb-5">Bubble Sort Visualization</h1>
        <form>
            <div class="form-row">
                <div class="col-sm-8">
                    <label for="input" class="sr-only">Enter a list of numbers:</label>
                    <input type="text" class="form-control" id="input" v-model="input" placeholder="Enter a list of numbers">
                </div>
                <div class="col-sm-4">
                    <button type="button" class="btn btn-primary btn-block" id="sort-button" @click="sort">Sort</button>
                </div>
            </div>
            <br>
            <div id="output"></div>
            <div class="row">
                <div class="col-sm-12 col-md">
                    <h3 class="text-center" id="step-label">Step 0 of 0</h3>
                </div>
                <div class="col-sm">
                    <div class="btn-group">
                        <button v-show="currentFrame >= 0" type="button" class="btn btn-secondary" @click="prevStep">Prev Step</button>
                        <button type="button" class="btn" id="play-button" @click="play">
                            <svg viewBox="0 0 100 100" width="50%">
                                <polygon points="0,0 0,100 100,50" fill="#fff"></polygon>
                            </svg>
                        </button>
                        <button v-show="currentFrame < maxFrame" type="button" class="btn btn-primary" @click="nextStep">Next Step</button>
                        <button v-show="currentFrame == maxFrame" type="button" class="btn btn-secondary" @click="restart">Restart</button>
                    </div>
                </div>
            </div>
        </form>
    </div>

    <script src="https://cdn.bootcss.com/vue/2.6.11/vue.min.js"></script>
    <script src="https://cdn.bootcss.com/jquery/3.3.1/jquery.min.js"></script>
    <script src="https://cdn.bootcss.com/bootstrap/4.3.1/js/bootstrap.min.js"></script>

    <script>
        new Vue({
      
      
            el: '#app',
            data: {
      
      
                input: '5, 4, 3, 2, 1',
                history: [],
                currentFrame: -1,
                maxFrame: -1,
                intervalId: null,
            },
            methods: {
      
      
                sort() {
      
      
                    this.history = [];
                    let list = this.input.split(',').map(Number);
                    let maxHeight = 10;
                    this.render(list.slice(), maxHeight);
                    for (let i = 0; i < list.length - 1; i++) {
      
      
                        for (let j = 0; j < list.length - i - 1; j++) {
      
      
                            if (list[j] > list[j + 1]) {
      
      
                                let temp = list[j];
                                list[j] = list[j + 1];
                                list[j + 1] = temp;
                                this.history.push(list.slice());
                            }
                        }
                    }
                    this.history.push(list.slice());
                    this.maxFrame = this.history.length - 1;
                    this.currentFrame = 0;
                    this.render(this.history[this.currentFrame], maxHeight);
                    this.updateLabel();
                },
                render(list, maxHeight) {
      
      
                    let outputDiv = document.getElementById('output');
                    outputDiv.innerHTML = '';
                    let scaleFactor = maxHeight / Math.max(...list);
                    for (let i = 0; i < list.length; i++) {
      
      
                        let bar = document.createElement('div');
                        bar.className = 'bar';
                        bar.style.height = `${ 
        scaleFactor * 20 * list[i]}px`;
                        bar.innerText = list[i].toString();
                        outputDiv.appendChild(bar);
                    }
                },
                nextStep() {
      
      
                    if (this.currentFrame < this.maxFrame) {
      
      
                        this.currentFrame++;
                        this.render(this.history[this.currentFrame], 10);
                        this.updateLabel();
                    }
                },
                prevStep() {
      
      
                    if (this.currentFrame > 0) {
      
       // 当前帧数大于0时才执行操作
                        this.currentFrame--;
                        this.render(this.history[this.currentFrame], 10);
                        this.updateLabel();
                    }
                },
                restart() {
      
      
                    this.currentFrame = -1;
                    this.sort();
                },
                updateLabel() {
      
      
                    let label = `Step ${ 
        this.currentFrame + 1} of ${ 
        this.maxFrame + 1}`;
                    document.getElementById('step-label').innerText = label;
                },
                play() {
      
      
                    if (this.intervalId) {
      
      
                        clearInterval(this.intervalId);
                        this.intervalId = null;
                    } else {
      
      
                        this.intervalId = setInterval(() => {
      
      
                            if (this.currentFrame < this.maxFrame) {
      
      
                                this.nextStep();
                            } else {
      
      
                                clearInterval(this.intervalId);
                                this.intervalId = null;
                            }
                        }, 500);
                    }
                },
            },
            mounted() {
      
      
                this.sort();
            },
        });
    </script>
</body>

</html>

特筆すべきは、この結果は、chatgpt で何度も通信を行った後に得られるものであり、ゆっくりと誘導する必要があるということです。

サポートエディター

次はアップグレードです。エディタにchatgptを参加させていますが、この部分はパフォーマンスが良くなく、ただ棚を置いているだけで、主にロジックを自分で実装しているため、ここでは手動で修正および追加しましたパーツ もちろん、コードは大したものではありません。追加のエディターにすぎず、入力コードを読み取るためのパーツを追加しますが、それだけでは十分ではありません。ここではセキュリティ フィルターなしで eval のみを使用して実装されており、ローカルで実行されます。 JavaScript のみをサポートします。

完全なコードは次のようになります。

<!DOCTYPE html>
<html>

<head>
    <meta charset="UTF-8">
    <title>666算法可视化平台</title>
    <link rel="stylesheet" href="https://cdnjs.cloudflare.com/ajax/libs/codemirror/5.62.0/codemirror.min.css">
    <link rel="stylesheet" href="https://cdn.bootcss.com/bootstrap/4.3.1/css/bootstrap.min.css">
    <style>
        .bar {
      
      
            background-color: blue;
            margin: 2px;
            display: inline-block;
            vertical-align: bottom;
            width: 40px;
            text-align: center;
            color: white;
            font-weight: bold;
        }
        
        #output {
      
      
            margin-bottom: 20px;
        }
        
        #step-label {
      
      
            font-size: 24px;
            font-weight: bold;
            margin-top: 10px;
            width: 100%;
        }
        
        #app>form>.form-row {
      
      
            display: flex;
            align-items: center;
            justify-content: space-between;
        }
        
        #app>form>.form-row>.col-sm-8 {
      
      
            display: flex;
            align-items: center;
            padding-right: 5px;
        }
        
        #app>form>.form-row>.col-sm-4 {
      
      
            display: flex;
            align-items: center;
            flex-wrap: nowrap;
            padding-left: 5px;
            width: 60px;
        }
        
        #sort-button {
      
      
            width: 70px !important;
            text-overflow: ellipsis;
            white-space: nowrap;
            overflow: hidden;
            margin-left: 1px;
        }
        
        #app>.row>.col-sm:not(:first-child) {
      
      
            margin-top: 10px;
        }
        
        #play-button {
      
      
            background-color: #007bff;
            color: white;
            border: none;
            font-weight: bold;
            width: 40px;
            height: 40px;
            border-radius: 50%;
            position: relative;
            transition: all .2s ease-in-out;
        }
        
        #play-button:hover {
      
      
            opacity: 0.8;
        }
        
        #play-button:active:after {
      
      
            content: "";
            display: block;
            position: absolute;
            top: 50%;
            left: 50%;
            transform: translate(-50%, -50%);
            width: 0;
            height: 0;
            border-style: solid;
            border-width: 10px 0 10px 20px;
            border-color: transparent transparent transparent #fff;
        }
        
        .btn-group>.btn {
      
      
            margin-left: 5px;
            margin-right: 5px;
        }
    </style>
</head>

<body>
    <div id="app" class="container mt-5">
        <h1 class="mb-5">666算法可视化平台</h1>
        <form>
            <div class="form-row">
                <div class="col-sm-8">
                    <label for="input" class="sr-only">Enter a list of numbers:</label>
                    <input type="text" class="form-control" id="input" v-model="input" placeholder="Enter a list of numbers">
                </div>
                <div class="col-sm-4">
                    <button type="button" class="btn btn-primary btn-block" id="sort-button" @click="sort">Sort</button>
                </div>
            </div>
            <br>
            <div id="output"></div>
            <div class="row">
                <div class="col-sm-12 col-md">
                    <h3 class="text-center" id="step-label">Step 0 of 0</h3>
                </div>
                <div class="col-sm">
                    <div class="btn-group">
                        <button v-show="currentFrame >= 0" type="button" class="btn btn-secondary" @click="prevStep">Prev Step</button>
                        <button type="button" class="btn" id="play-button" @click="play">
                            <svg viewBox="0 0 100 100" width="50%">
                                <polygon points="0,0 0,100 100,50" fill="#fff"></polygon>
                            </svg>
                        </button>
                        <button v-show="currentFrame < maxFrame" type="button" class="btn btn-primary" @click="nextStep">Next Step</button>
                        <button v-show="currentFrame == maxFrame" type="button" class="btn btn-secondary" @click="restart">Restart</button>
                    </div>
                </div>
            </div>
            <textarea id="code"></textarea>
        </form>

    </div>

    <script src="https://cdn.bootcss.com/vue/2.6.11/vue.min.js"></script>
    <script src="https://cdn.bootcss.com/jquery/3.3.1/jquery.min.js"></script>
    <script src="https://cdn.bootcss.com/bootstrap/4.3.1/js/bootstrap.min.js"></script>
    <script src="https://cdnjs.cloudflare.com/ajax/libs/codemirror/5.62.0/codemirror.min.js"></script>
    <script src="https://cdnjs.cloudflare.com/ajax/libs/codemirror/5.62.0/mode/javascript/javascript.min.js"></script>

    <script>
        new Vue({
      
      
            el: '#app',
            data: {
      
      
                input: '5, 4, 3, 2, 1',
                history: [],
                currentFrame: -1,
                maxFrame: -1,
                intervalId: null,
                editor: null,
                code: `//欢迎使用666可视化工具,目前只支持JS
function bubbleSort(arr,that) {
// arr是固定参数
  let len = arr.length;
  for (let i = 0; i < len - 1; i++) {
    for (let j = 0; j < len - i - 1; j++) {
      if (arr[j] > arr[j + 1]) {
        let temp = arr[j];
        arr[j] = arr[j + 1];
        arr[j + 1] = temp;

        // 存储每一次交换的结果,固定格式
        that.history.push(arr.slice());
      }
    }
  }
}`
            },
            methods: {
      
      
                sort() {
      
      
                    this.history = [];
                    let list = this.input.split(',').map(Number);
                    let maxHeight = 10;
                    this.render(list.slice(), maxHeight);

                    if (this.hasCode()) {
      
      
                        let coeds = this.getCode()
                        let fn = eval(`(${ 
        coeds})`);
                        fn(list, this);
                    } else {
      
      
                        for (let i = 0; i < list.length - 1; i++) {
      
      
                            for (let j = 0; j < list.length - i - 1; j++) {
      
      
                                if (list[j] > list[j + 1]) {
      
      
                                    let temp = list[j];
                                    list[j] = list[j + 1];
                                    list[j + 1] = temp;
                                    this.history.push(list.slice());
                                }
                            }
                        }
                    }

                    this.history.push(list.slice());
                    this.maxFrame = this.history.length - 1;
                    this.currentFrame = 0;
                    this.render(this.history[this.currentFrame], maxHeight);
                    this.updateLabel();
                },
                render(list, maxHeight) {
      
      
                    let outputDiv = document.getElementById('output');
                    outputDiv.innerHTML = '';
                    let scaleFactor = maxHeight / Math.max(...list);
                    for (let i = 0; i < list.length; i++) {
      
      
                        let bar = document.createElement('div');
                        bar.className = 'bar';
                        bar.style.height = `${ 
        scaleFactor * 20 * list[i]}px`;
                        bar.innerText = list[i].toString();
                        outputDiv.appendChild(bar);
                    }
                },
                nextStep() {
      
      
                    if (this.currentFrame < this.maxFrame) {
      
      
                        this.currentFrame++;
                        this.render(this.history[this.currentFrame], 10);
                        this.updateLabel();
                    }
                },
                prevStep() {
      
      
                    if (this.currentFrame > 0) {
      
       // 当前帧数大于0时才执行操作
                        this.currentFrame--;
                        this.render(this.history[this.currentFrame], 10);
                        this.updateLabel();
                    }
                },
                restart() {
      
      
                    this.currentFrame = -1;
                    this.sort();
                },
                updateLabel() {
      
      
                    let label = `Step ${ 
        this.currentFrame + 1} of ${ 
        this.maxFrame + 1}`;
                    document.getElementById('step-label').innerText = label;
                },
                play() {
      
      
                    if (this.intervalId) {
      
      
                        clearInterval(this.intervalId);
                        this.intervalId = null;
                    } else {
      
      
                        this.intervalId = setInterval(() => {
      
      
                            if (this.currentFrame < this.maxFrame) {
      
      
                                this.nextStep();
                            } else {
      
      
                                clearInterval(this.intervalId);
                                this.intervalId = null;
                            }
                        }, 500);
                    }
                },
                getCode() {
      
      
                    return this.editor.getValue();
                },
                hasCode() {
      
      
                    let code = this.getCode();
                    return code.trim().length > 0;
                },
            },

            mounted() {
      
      

                this.editor = CodeMirror.fromTextArea(document.getElementById("code"), {
      
      
                    lineNumbers: true,
                    mode: "text/javascript",
                    tabSize: 2,
                    theme: "default",
                });
                this.editor.setValue(this.code);
                this.sort();
            },
        });
    </script>
</body>

</html>

要約する

一人がチーム、それは今後は冗談ではなくなります。将来的に考えてみましょう、コストを節約するためにボスを開くべきですか、それとも収入を増やすためにボスを開くべきですか?

おすすめ

転載: blog.csdn.net/FUTEROX/article/details/130096810