【问题标题】:Count vowels and consonants in an array计算数组中的元音和辅音
【发布时间】:2021-08-07 17:21:34
【问题描述】:

我正在尝试编写一个function,它将返回元音的数量 和辅音。使用IF语句函数会成功 编译,但是当我在选择中调用它时,它会显示消息:

"将 varchar 值 'MAMAMIA' 转换为 数据类型 int。"`

我尝试使用CASE 语句,但语法太多 错误,我认为这不是解决问题的最佳方法 使用 CASE ...

 CREATE FUNCTION VOW_CONS(@ARRAY VARCHAR(20))
 RETURNS INT
 BEGIN

 DECLARE @COUNTT INT;
 DECLARE @COUNTT1 INT; 
 
 SET @COUNTT=0;
 SET @COUNTT1=0;

 WHILE (@ARRAY!=0)
 BEGIN
  IF(@ARRAY LIKE '[aeiouAEIOU]%') 
 
 SET @COUNTT=@COUNTT+1 

 ELSE SET @COUNTT1=@COUNTT1+1

/*
 DECLARE @C INT; 
SET @C=(CASE @SIR WHEN 'A' THEN  @COUNTT=@COUNTT+1; 
        WHEN 'E' THEN  @COUNTT=@COUNTT+1
        WHEN 'I' THEN  @COUNTT=@COUNTT+1
        WHEN 'O' THEN  @COUNTT=@COUNTT+1 
        WHEN 'U' THEN  @COUNTT=@COUNTT+1 
        WHEN 'A' THEN  @COUNTT=@COUNTT+1
        WHEN ' ' THEN ' '
   ELSE  @COUNTT1=@COUNTT1+1
   END) 
*/

 END

  RETURN @COUNTT;

END

SELECT DBO.VOW_CONS('MAMAMIA')

【问题讨论】:

  • 请不要对我们大喊大叫;我们可以很好地阅读小写/正确的大小写文本,谢谢。
  • SQL Server 不支持数组,这是什么意思?您是否传递了一个分隔的字符串列表?您的字符串可以包含 A-z 以外的其他字符吗?你说你在计算元音和辅音的数量,但是你有一个标量函数,那么你如何在这里返回 2 个值?
  • 至于如果@ARRAY 中有任何非数字字符,则错误WHILE (@ARRAY!=0) 将不起作用。但是,我不知道该表达式是什么意思,因为@COUNTT@COUNTT1 在前面的语句中都被赋值为0;所以如果你检查它们的值,那么WHILE 将永远不会被输入,如果你给它们分配一个大于零的值,它看起来会无限循环。
  • 对不起大写我习惯于使用大写锁定在 SQL Server 中编写代码。我正在传递一个字符串列表,它不能包含 A-z 以外的其他字符。我的第一个任务是只计算元音,但它也必须计算辅音,因此以后应该编辑代码。 @COUNTT@COUNTT1 最初设置为 0,因为我打算将它们用作计数器,首先将计算元音,第二个辅音。让我知道我是否可以编写如下语法:declare @position int set @position=0 While(@position<len(@ARRAY@)) ?
  • "我正在传递一个字符串列表,它不能包含除 Az 以外的其他字符。" 如果是字符串列表,但值不能包含字符除了 Az,你怎么知道一个字符串在哪里结束,另一个字符串从哪里开始......?示例数据和预期结果将真正帮助我们在这里为您提供帮助。另外,您使用的是什么版本的 SQL Server?

标签: function tsql if-statement switch-statement


【解决方案1】:

在不知道您使用的是什么版本的 SQL Server 的情况下,我将假设您使用的是最新版本,这意味着您可以访问 TRANSLATE。另外,我将假设您 确实 需要访问元音 辅音的数量,因此表值函数在这里似乎是更好的方法。因此,您可以执行以下操作:

CREATE FUNCTION dbo.CountVowelsAndConsonants (@String varchar(20)) 
RETURNS table
AS RETURN
    SELECT DATALENGTH(@String) - DATALENGTH(REPLACE(TRANSLATE(@String,'aeiou','|||||'),'|','')) AS Vowels, --Pipe is a character that can't be in your string
           DATALENGTH(@String) - DATALENGTH(REPLACE(TRANSLATE(@String,'bcdfghjklmnpqrstvwxyz','|||||||||||||||||||||'),'|','')) AS Consonants --Pipe is a character that can't be in your string
GO

然后你可以像这样使用函数:

SELECT *
FROM (VALUES('MAMAMIA'),('Knowledge is power'))V(YourString)
     CROSS APPLY dbo.CountVowelsAndConsonents(V.YourString);

【讨论】:

  • 我使用的是 SQL Server 2014 感谢参考!
  • 然后你需要做一堆嵌套替换,@NicolaevMaxim。虽然您不需要用管道 (|) 和零长度字符串 ('') 替换字符;您可以将每个字符直接替换为长度为零的字符串。
【解决方案2】:

另一种选择是使用计数表将字符串拆分为单独的字母,将其连接到元音/辅音表中,然后进行计数。

这是一个工作示例,您必须根据自己的特定需求进行更新/更改,但应该让您了解它的工作原理。

DECLARE @string NVARCHAR(100)

SET @string = 'Knowledge is power';

--Here we build a table of all the letters setting a flag on which ones are vowels
DECLARE @VowelConsonants TABLE
    (
        [Letter] CHAR(1)
      , [IsVowel] BIT
    );

--We load it with the data
INSERT INTO @VowelConsonants (
                                 [Letter]
                               , [IsVowel]
                             )
VALUES ( 'a', 1 ) , ( 'b', 0 ) , ( 'c', 0 ) , ( 'd', 0 ) , ( 'e', 1 ) , ( 'f', 0 ) , ( 'g', 0 ) , ( 'h', 0 ) , ( 'i', 1 ) , ( 'j', 0 ) , ( 'k', 0 ) , ( 'l', 0 ) , ( 'm', 0 ) , ( 'n', 0 ) , ( 'o', 1 ) , ( 'p', 0 ) , ( 'q', 0 ) , ( 'r', 0 ) , ( 's', 0 ) , ( 't', 0 ) , ( 'u', 1 ) , ( 'v', 0 ) , ( 'w', 0 ) , ( 'x', 0 ) , ( 'y', 0 ) , ( 'z', 0 );

--This tally table example gives 10,000 numbers
WITH
    E1(N) AS (select 1 from (values (1),(1),(1),(1),(1),(1),(1),(1),(1),(1))dt(n)),
    E2(N) AS (SELECT 1 FROM E1 a, E1 b), --10E+2 or 100 rows
    E4(N) AS (SELECT 1 FROM E2 a, E2 b), --10E+4 or 10,000 rows max
    cteTally(N) AS 
    (
        SELECT  ROW_NUMBER() OVER (ORDER BY (SELECT NULL)) FROM E4
    )
SELECT     SUM(   CASE WHEN [vc].[IsVowel] = 1 THEN 1
                       ELSE 0
                  END
              ) AS [VowelCount]
         , SUM(   CASE WHEN [vc].[IsVowel] = 0 THEN 1
                       ELSE 0
                  END
              ) AS [ConsonantCount]
FROM       [cteTally] [t] --Select from tally cte
INNER JOIN @VowelConsonants [vc]  --Join to VowelConsonants table on the letter.
    ON LOWER([vc].[Letter]) = LOWER(SUBSTRING(@string, [t].[N], 1))  --Using the number from the tally table we can easily split out each letter using substring
WHERE      [t].[N] <= LEN(@string);

为您提供以下结果:

VowelCount  ConsonantCount
----------- --------------
6           10

【讨论】:

    猜你喜欢
    • 1970-01-01
    • 2018-01-14
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2020-04-02
    • 1970-01-01
    相关资源
    最近更新 更多